¿Cuál es la esencia de permitir que el usuario cree un hilo extendiendo la clase Thread cuando podemos lograr la misma funcionalidad implementando Runnable y pasándolo al constructor Thread?¿Por qué la clase java.lang.Thread en Java no está marcada como definitiva por los diseñadores?
Respuesta
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.
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.
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()
).
+1 Gran idea .. – Daniel
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()
).
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.
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.
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.
- 1. ¿Por qué la memoria no asignada está marcada como 0xCC?
- 2. ¿Por qué la clase String es definitiva?
- 3. ¿Está marcada la clase de excepción java?
- 4. ¿Por qué la tabla hash de HashMap está marcada como transitoria aunque la clase es serializable?
- 5. ¿Por qué una enum de Java no puede ser definitiva?
- 6. ¿Por qué NullPointerException no se declara como una excepción marcada?
- 7. java: ¿Por qué la variable local debe ser declarada definitiva
- 8. ¿Por qué la clase de entidad en JPA no puede ser definitiva?
- 9. En Java, ¿cómo serializo una clase que no está marcada como Serializable?
- 10. ¿Por qué una variable de miembro Object no puede ser definitiva y volátil en Java?
- 11. Java: averiguar * por qué * una clase está cargada
- 12. ¿Por qué GetHashCode está en la clase Object?
- 13. RadioButtonList marcada por defecto
- 14. ¿Por qué Java está etiquetado como un lenguaje "seguro"?
- 15. ¿Por qué Java no pudo encontrar la clase principal?
- 16. ¿Por qué no está disponible getClass() como método estático?
- 17. ¿Por qué no se implementa JML como anotaciones en Java?
- 18. ¿Por qué está String.Format estático?
- 19. ¿Por qué la clase Singleton debe sellarse?
- 20. ¿Por qué mi clase no es aceptable?
- 21. ¿Por qué evento listview fuego que indica que elemento seleccionado no está marcada después de añadir
- 22. ¿por qué no está (123 == 0123) en java?
- 23. ¿Por qué Java's Double.compare (doble, doble) está implementado como está?
- 24. ¿Por qué no puedo editar los valores en mi DataGridView, aunque no está configurado como ReadOnly?
- 25. ¿Es java.lang.Thread una clase segura para subprocesos?
- 26. ¿Por qué obtengo los métodos de la clase base por reflexión cuando la subclase los anula?
- 27. ¿Por qué los diseñadores de C# asociaron tres significados diferentes a la palabra clave 'usar'?
- 28. Por qué está fallando Java en la anotación @Override
- 29. ¿Por qué los métodos Java con varargs identificados como transitorios?
- 30. ¿Por qué está certificado TomEE Java EE6 pero TomEE + no?
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). –
@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
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