thread example español java runnable

java - example - ¿Por qué Thread implementa Runnable?



thread pool java (2)

La JVM llama al método run() un subproceso Java, en ese subproceso, cuando se inicia el subproceso. Para darle a un hilo algo que hacer, puede crear una subclase de Hilo y anular su método run (), o (preferido) puede proporcionar un Runnable al constructor del hilo. Esta bien.

Estaba en medio de hacer una subclase de Thread y reemplazar la ejecución, y me di cuenta de que no podía hacer el método protegido como esperaba porque Thread.run () es público. Entonces me di cuenta por qué: tiene que ser público porque Thread implementa Runnable. ¿Pero por qué implementa Runnable?

No parece lógico. Un hilo es iniciable (del hilo actual), pero no lo ejecuta de la misma manera que ejecuta () un Runnable (del hilo actual); el hilo se ejecuta solo (en su propio hilo). Si llamas manualmente al método de ejecución de un Thread, entonces no lo estás usando como un Thread, solo un Runnable pesado.

Debido al diseño, cualquier código con acceso a un objeto Thread puede llamar a su método de ejecución pública y potencialmente introducir en un código que no está destinado a ser público o diseñado para ser llamado de esa manera. También permite cosas muy peculiares como esta:

Thread.currentThread.run();

¿Existe un uso legítimo para Thread que implementa Runnable que no estoy viendo?


Sin embargo, la ejecución principal no explica por qué alguna vez tuvo que ser público.

Si este es su problema, creo que hay una respuesta simple para eso: los métodos que implementan una interfaz siempre deben ser públicos en Java. Sería posible con una clase abstracta para que esté protegida, pero si Thread fuera abstracto, no podrías usarlo como tal.

En cuanto a por qué es Thread la implementación de Runnable en primer lugar, Java debe tener una forma de saber en qué parte del hilo está realmente haciendo su trabajo. Usan el método run para eso. Podrían haber separado más claramente la lógica de solo implementar Runnable y hacer que la subclase Thread implemente eso, pero eso es lo que considero un error menor que es difícil de cambiar debido a razones históricas.

TLDR; AFAIK realmente no hay una buena razón para que un Thread implemente Runnable, pero hay razones para que implemente algún tipo de interfaz como esa: deberían haber tenido algún tipo de interfaz separada como ThreadRunnable en lugar de usar la misma Interfaz ejecutable que también tiene otros usos.

Tenga en cuenta también que en java moderno probablemente debería usar Callables y FutureTasks en lugar de Threads. "La integración de los tiempos de espera, la cancelación adecuada y la agrupación de subprocesos de la compatibilidad de concurrencia moderna son mucho más útiles para mí que las pilas de subprocesos sin procesar", citando otra respuesta aquí en .


La razón es la "compatibilidad hacia atrás".

La clase Thread originó en Java 1.0 ... o anterior. En aquellos días, Java no tenía clases internas, por lo que no había una forma ligera de implementar una instancia de Runnable . Si observa ejemplos y tutoriales antiguos de subprocesos de esa época, es común ver clases que amplían Thread y anulan el método run() .

Con el tiempo, se descubrió que extender Thread no es una buena idea (por varias razones). Sin embargo, el diseño de Thread no se pudo cambiar porque eso hubiera hecho que el código Java antiguo fuera incompatible con las JVM más nuevas.

¿Existe un uso legítimo para Thread que implementa Runnable que no estoy viendo?

Depende de lo que entiendas por "legítimo".

  • El código antiguo que se escribió en los primeros días no es "ilegítimo" en virtud de hacer las cosas a la manera antigua. No hay nada "roto" al respecto.

  • Hay escenarios potenciales donde tiene sentido extender Thread y anular el método run() . Por ejemplo, es posible que desee que run() implemente algún mecanismo especial para pasar información dentro o fuera del Runnable suministrado, o que implemente un manejo especial de excepciones, o ... haga que el hilo sea "reiniciable".

  • Incluso puede haber situaciones en las que desee llamar a run() directamente en un objeto de subproceso. Por ejemplo, si le entregaron un código de "desayuno de perros" con Thread ampliado y tuvo que convertirlo para ejecutarlo en un grupo de subprocesos sin modificar el código original. Podría considerar crear una instancia de la clase de subproceso crufty y pasar las instancias como runnables a la agrupación de subprocesos para ejecutar. (Sí ... horrible!)