2010-05-06 22 views

Respuesta

8

De esta manera usted desacoplar el cálculo (el qué) de la ejecución (el cuándo y/o la forma en ).

Con Runnable o Callable, puede por ejemplo enviar muchos trabajos/cálculos a un Executor que se ocupará de programar el material. He aquí un extracto forma ExecutorService:

pool = Executors.newFixedThreadPool(poolSize); 
... 
pool.execute(new Handler(serverSocket.accept())); 
... 
class Handler implements Runnable { 
    ... 
} 

Usando Runnable/Callable le da más flexibilidad que el uso de hilos directamente.

+0

también para que tu ejecutable pueda extender otras clases que no sean Thread –

2

Puede tener sentido en sus jerarquías de herencia extender Thread. Extienda solo Thread si desea modificar la funcionalidad de Thread s.

Con Runnable, cualquier clase en cualquier jerarquía de herencia puede exponer una tarea que se puede ver como una unidad de trabajo para realizar un Thread.

3

Porque IS-A realmente no es lo que quieres. Tu clase quiere ser Runnable, pero IS-A Thread se siente demasiado fuerte. Eso es lo que dice la herencia. Realmente solo desea implementar el método run(), no todas las demás cosas de la clase Thread.

Esto coincide con los muy buenos consejos de Scott Meyers en "C++ más efectivo": hacer que las clases que no sean hojas sean abstractas. Interfaces sustitutos y estás en el blanco.

18

El punto real para llevar es que los implementos SIEMPRE son preferibles a los extendidos en cualquier caso cuestionable.

Extiende enlaza dos archivos de clase muy de cerca y puede causar problemas con el código.

Cuando por primera vez "entendí" la programación OO, estaba extendiendo TODO, pero convirtió todo mi diseño en papilla. Ahora extiendo solo las pocas cosas que claramente y obviamente pasan la prueba "es-a" y todo lo demás es una interfaz ...

Muchos problemas simplemente dejaron de suceder (Confundir situaciones de herencia múltiples, jerarquías de refactorización desperdiciadas en el tiempo, tendencia a tener variables "protegidas" y luego preguntarse por qué están cambiando cuando no las modificó en la clase actual, encadenando requisitos para los constructores, descubriendo cómo diferentes árboles de herencia interactúan entre sí, ...

parece que cada 3 años (durante los últimos 20) creo que realmente "entiendo" la programación y miro hacia atrás a las cosas estúpidas que hice hace 3 años por vergüenza ...Este fue uno de esos casos (pero a partir de cerca de 7 años atrás en este punto)

2

Las razones por las que podría preferir la aplicación de la Interface Runnable a extender el Class Thread son los siguientes:

  • menos sobrecarga en un contexto secuencial (source)

Cuando se extiende clase thread, cada uno de su hilo crea única obj ect y asociarse con ella. Cuando implementa Runnable, comparte el mismo objeto en varios subprocesos.

Fuente: a blog - No estoy muy seguro de si eso es correcto

  • puede enviar tareas en la red con Ejecutable (Tema ¿no serializable, source)
  • mejor programación orientada a objetos -style
    • es muy probable que no tenga una relación "es una"
    • que tienen la posibilidad de extender otras clases (Java no tiene herencia múltiple)
0

Para responder a la pregunta primero:

Si se extiende el hilo, una instancia de su clase (rosca extendida) siempre llamará al constructor del subproceso de la superclase. Así que MyClass myclass = new MyClass() siempre llamará a "super()" dentro del constructor de MyClass que crea una secuencia y, al final, podrá implementar algunos gastos generales en su clase (si no utiliza ningún método de el hilo de la superclase). Por lo tanto, implementar Runnable solo permite que su clase se ejecute más rápido sin ninguna sobrecarga hereditaria.

Además, hay algunas respuestas incorrectas aquí:

Ahora se extienden sólo las pocas cosas que claramente y obviamente pasan el "es-un" ensayo y todo lo demás es una interfaz ...

¿Alguna vez pensó en crear un objeto sin interfaz? ¡Porque sería muy incorrecto implementar una interfaz para cada objeto!

Cuando extiende la clase de subprocesos, cada subproceso crea un objeto único y se asocia con él. Cuando implementa Runnable, comparte el mismo objeto con múltiples hilos.

¡Incorrecto, cada vez que llame al constructor de una clase, obtendrá un objeto propio, no importa desde dónde se extiende o qué implementa!

Conclusión: En java, CADA instancia de clase es un objeto y amplía la clase Objeto (mientras que las primitivas no ...solo la matriz de primitivas como las clases int [] amplía Object, y dichas matrices tienen los mismos métodos que cualquier objeto, ¡pero sadely no se mencionan en el Javadoc! Los chicos de Sun probablemente no querían que los usáramos).

Por cierto, hay al menos dos ventajas de la herencia: el código compartido y un claro Javadoc. Porque si heredas de una clase, puedes ver todas las subclases en el Javadoc. También puedes hacer eso con una interfaz, pero luego no puedes compartir el código. Aún más, entonces necesitaría crear objetos "anidados" y llamar al constructor de dos o más objetos en lugar de solo uno, y esto nuevamente significaría que usted implementaría una sobrecarga del objeto de la superclase. Debido a que no hay ningún objeto en Java sin gastos generales, y la creación de menos objetos como sea posible es muy importante para las aplicaciones de alto rendimiento. Los objetos son lo mejor, pero los objetos innecesarios no son ...

Cuestiones relacionadas