Respuesta

2

Thread es inusual en que puede hacer referencia al Runnable para ejecutarse, pero también es Runnable. De forma predeterminada, el Thread se usará como la instancia Runnable para ejecutarse, aunque, por supuesto, puede señalarlo en otro lugar.

creo que eso no es una buena razón para las dos marcas Thread final y requerir una Runnable externa o para hacer Thread extensible y tiene que ser su propio Runnable. Ambos enfoques están perfectamente bien y ninguno parece una elección mucho mejor que el otro.

Si tuviera que adivinar, la razón para hacer Thread subclases es que le permite escribir código como este:

Thread t = new Thread() { 
    public void run() { 
     /* ... your code here ... */ 
    } 
}; 

Cuál es marginalmente más limpio que la creación de una subclase de Runnable y luego envolverlo en una hilo. Del mismo modo, puede crear una subclase fuera de Thread para obtener un Runnable que indique claramente que se supone que debe utilizarse como un hilo. Por supuesto, esto es principalmente una cuestión de estética, y si los diseñadores de Java hubieran optado por el otro lado con esto, creo que hubiera sido una decisión perfectamente buena.

+0

Es más limpio en un sentido de sintaxis, pero no más limpio en un sentido de diseño y puede tener implicaciones crueles (pérdida de perm gen) cuando el cargador de clase actual está descargado (por ejemplo, en el servidor de aplicaciones). –

+0

@Piotr, la basura de la clase y todo el jazz estático, lamentablemente, no se resolverá simplemente no anulando el hilo, el CCL se mantiene como referencia incluso en los hilos muertos, que solo puede causar daño suficiente. inheritedAccessControlContext y runnable se mantienen en ejecución de subprocesos, por lo que gran diferencia imo. – bestsss

+0

anulando el hilo tiene algunas implicaciones, como hacer un seguimiento de las subclases de subprocesos peligrosos (tales que anula get/setContextClassLoader()) que da como resultado algunas operaciones y sincronizaciones adicionales. 'Thread.isCCLOverridden (Class)' – bestsss

0

Una diferencia notable es que si su clase A necesita extender una clase B (diferente a la cadena) Y ser una cadena al mismo tiempo, deberá implementar Runnable.

3

conseguir la misma funcionalidad por implementar Ejecutable y pasarlo a el constructor Thread

El uso de extender hilo no se limita a Ejecutable. Por ejemplo, puede change the behavior of some methods o agregar su propio hilo de información local (siempre accesible con Thread.currentThread()).

+0

+1 Gran idea .. – Daniel

0

Si ACAN añadir algo, extendiendo Thread se puede haber extendido la funcionalidad de un hilo (que es no existe en Runnable ya que sólo contiene el método run()) como permitir que el hilo para que actúe como un hilo demonio (al igual que el subproceso Daemon del recopilador de basura). Existen otros hilos como el único hilo que no es daemon que llama al método principal de una clase (cuando se inicia JVM).

La interfaz Runnable permite que su clase se active como subproceso (implementando un método run()).

3

Desde una perspectiva histórica, debe comprender que la API Thread se diseñó en Java 1.0, antes de que Java admitiera clases internas anónimas. Y gran parte del código de ejemplo anterior muestra la subclasificación de Thread. No fue hasta más tarde que:

  • agregaron soporte para clases internas anónimas (Java 1.1)
  • descubrieron que era mejor usar clases internas (etc.) para proporcionar Runnable instancias
  • implementaron clases estándar para la ejecución de tareas, grupos de subprocesos, etc. (Java 5.0).

Es muy bien decir "la clase Thread en .Net está marcada final", pero hay que darse cuenta de que C#/.NET llegaron a lo largo de varios años más tarde ... y era capaz de aprende del diseño de Java. Java estaba/está atascado con el bagaje histórico de una serie de decisiones de diseño menos que perfectas ... debido a un imperativo primordial de NO romper el código anterior.

0

La clase de subprocesos describe cómo se ejecuta el subproceso, Runnable describe qué se ejecuta. Si desea modificar lo que se ejecuta, debe implementar Runnable. Si desea modificar cómo se ejecuta el hilo, deriva de Thread. En el caso en que desee modificar cómo se ejecuta un subproceso, puede derivar del Subproceso e implementar un objeto Runnable independiente.

0

Lo único bueno que se me ocurre es: si extiende la clase Thread, le permite a su método run() marcarse como protected. Una desventaja de la aplicación de Ejecutable es que su método run deben estar marcados como públicos.

Cuestiones relacionadas