"implements Runnable" vs "extends Thread" en Java
Desde el tiempo que he pasado con subprocesos en Java, he encontrado estas dos formas de escribir subprocesos:
Con implements Runnable
:
public class MyRunnable implements Runnable {
public void run() {
//Code
}
}
//Started with a "new Thread(new MyRunnable()).start()" call
O con extends Thread
:
public class MyThread extends Thread {
public MyThread() {
super("MyThread");
}
public void run() {
//Code
}
}
//Started with a "new MyThread().start()" call
¿hay alguna diferencia significativa en estos dos bloques de código ?
30 answers
Sí: implementa Runnable
es la forma preferida de hacerlo, IMO. No estás realmente especializando el comportamiento del hilo. Sólo le estás dando algo para correr. Eso significa quela composición es elfilosóficamente camino "más puro" a seguir.
En términos prácticos , significa que puede implementarRunnable
y extender desde otra clase también.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-22 22:09:24
Tl; dr: implements Runnable es mejor. Sin embargo, la advertencia es importante
En general, recomendaría usar algo como Runnable
en lugar de Thread
porque le permite mantener su trabajo solo vagamente acoplado con su elección de concurrencia. Por ejemplo, si usas un Runnable
y decides más tarde que esto no requiere que sea propio Thread
, puedes llamar a ThreadA.ejecutar().
Advertencia: Por aquí, desaconsejo fuertemente el uso de raw Hilo. Prefiero mucho el uso de Callables y FutureTasks (del javadoc: "Un cálculo asíncrono cancelable"). La integración de los tiempos de espera, la cancelación adecuada y la agrupación de subprocesos del soporte de concurrencia moderna son mucho más útiles para mí que las pilas de subprocesos sin procesar.
Seguimiento: hay un FutureTask
constructor que le permite usar Runnables (si eso es con lo que se siente más cómodo) y aún así obtener el beneficio de las herramientas modernas de concurrencia. Para citar el javadoc:
Si no necesita un resultado en particular, considere usar construcciones de la forma:
Future<?> f = new FutureTask<Object>(runnable, null)
Entonces, si reemplazamos su runnable
con su threadA
, obtenemos lo siguiente:
new FutureTask<Object>(threadA, null)
Otra opción que le permite estar más cerca de Runnables es un ThreadPoolExecutor. Puede usar el método execute para pasar un Ejecutable para ejecutar "la tarea dada en algún momento en el futuro."
Si quieres para intentar usar un grupo de subprocesos, el fragmento de código anterior se convertiría en algo como lo siguiente (usando los ejecutores .newCachedThreadPool () método de fábrica):
ExecutorService es = Executors.newCachedThreadPool();
es.execute(new ThreadA());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-28 07:26:50
Moraleja de la historia:
Heredar solo si desea anular algún comportamiento.
O más bien debe leerse como:
Heredar menos, interactuar más.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-28 16:26:50
Bueno, muchas buenas respuestas, quiero agregar más sobre esto. Esto ayudará a entender Extending v/s Implementing Thread
.
Extends enlaza dos archivos de clase muy de cerca y puede causar que algunos sean bastante difíciles de tratar con el código.
Ambos enfoques hacen el mismo trabajo, pero ha habido algunas diferencias.
La diferencia más común es
- Cuando extiende la clase Thread, después de eso no puede extender ninguna otra clase que necesite. (Como sabes, Java no permite heredar más de una clase).
- Cuando implementa Runnable, puede ahorrar un espacio para que su clase extienda cualquier otra clase en el futuro o ahora.
Sin embargo, una diferencia significativa entre implementar Ejecutable y extender Hilo es que
by extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same object instance.
El siguiente ejemplo le ayuda a entender más claramente
//Implement Runnable Interface...
class ImplementsRunnable implements Runnable {
private int counter = 0;
public void run() {
counter++;
System.out.println("ImplementsRunnable : Counter : " + counter);
}
}
//Extend Thread class...
class ExtendsThread extends Thread {
private int counter = 0;
public void run() {
counter++;
System.out.println("ExtendsThread : Counter : " + counter);
}
}
//Use above classes here in main to understand the differences more clearly...
public class ThreadVsRunnable {
public static void main(String args[]) throws Exception {
// Multiple threads share the same object.
ImplementsRunnable rc = new ImplementsRunnable();
Thread t1 = new Thread(rc);
t1.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
Thread t2 = new Thread(rc);
t2.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
Thread t3 = new Thread(rc);
t3.start();
// Creating new instance for every thread access.
ExtendsThread tc1 = new ExtendsThread();
tc1.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
ExtendsThread tc2 = new ExtendsThread();
tc2.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
ExtendsThread tc3 = new ExtendsThread();
tc3.start();
}
}
Salida del programa anterior.
ImplementsRunnable : Counter : 1
ImplementsRunnable : Counter : 2
ImplementsRunnable : Counter : 3
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
En el enfoque de interfaz ejecutable, solo una instancia de un la clase se está creando y ha sido compartida por diferentes hilos. Por lo tanto, el valor del contador se incrementa para cada acceso a subprocesos.
Considerando que, enfoque de clase de subproceso, debe tener que crear una instancia separada para cada acceso de subproceso. Por lo tanto, se asigna una memoria diferente para cada instancia de clase y cada una tiene un contador separado, el valor sigue siendo el mismo, lo que significa que no se producirá ningún incremento porque ninguna de las referencias del objeto es la misma.
Cuándo usar ¿Ejecutable?
Utilice la interfaz ejecutable cuando desee acceder al mismo recurso desde el grupo de subprocesos. Evite usar la clase Thread aquí, porque la creación de múltiples objetos consume más memoria y se convierte en una gran sobrecarga de rendimiento.
Una clase que implementa Runnable no es un subproceso sino solo una clase. Para que un Ejecutable se convierta en un Subproceso, debe crear una instancia de Subproceso y pasar a sí mismo como destino.
En la mayoría de los casos, se debe usar la interfaz ejecutable si solo está planeando sobreescribir el método run()
y ningún otro método de Subproceso. Esto es importante porque las clases no deben ser subclases a menos que el programador tenga la intención de modificar o mejorar el comportamiento fundamental de la clase.
Cuando es necesario extender una superclase, implementar la interfaz Ejecutable es más apropiado que usar la clase Thread. Porque podemos extender otra clase mientras implementamos una interfaz ejecutable para hacer un subproceso.
Espero que esto ¡ayudará!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-11 10:47:33
Una cosa que me sorprende que no se haya mencionado todavía es que implementar Runnable
hace que su clase sea más flexible.
Si extiendes el hilo, entonces la acción que estás haciendo siempre estará en un hilo. Sin embargo, si implementa Runnable
no tiene que ser. Puede ejecutarlo en un subproceso, o pasarlo a algún tipo de servicio ejecutor, o simplemente pasarlo como una tarea dentro de una sola aplicación enhebrada (tal vez para ejecutarse en un momento posterior, pero dentro del mismo subproceso). Las opciones son mucho más abierto si solo usas Runnable
que si te atas a Thread
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-12 12:53:26
Si desea implementar o extender cualquier otra clase, entonces la interfaz Runnable
es preferible de otro modo si no desea que ninguna otra clase se extienda o implemente, entonces Thread
la clase es preferible
La diferencia más común es
Cuando usted extends Thread
clase, después de que usted no puede extender cualquier otra clase que usted requiere. (Como sabes, Java no permite heredar más de una clase).
Cuando usted implements Runnable
, puede ahorrar un espacio para su clase para extender cualquier otra clase en el futuro o ahora.
Java no admite herencia múltiple, lo que significa que solo puede extender una clase en Java, por lo que una vez que extendió la clase Thread perdió su oportunidad y no puede extender o heredar otra clase en Java.
En la programación orientada a objetos extender una clase generalmente significa agregar nueva funcionalidad, modificar o mejorar comportamientos. Si no estamos haciendo ninguna modificación en el hilo, utilice la interfaz ejecutable en su lugar.
La interfaz ejecutable representa una Tarea que puede ser ejecutada por Subprocesos simples o Ejecutores o por cualquier otro medio. así que la separación lógica de la tarea como Ejecutable de hilo es una buena decisión de diseño.
Separar la tarea como ejecutable significa que podemos reutilizar la tarea y también tiene libertad para ejecutarla desde diferentes medios. ya que no puede reiniciar un hilo una vez que se complete. de nuevo Runnable vs Thread para la tarea, Runnable es ganador.
Java el diseñador reconoce esto y es por eso que los ejecutores aceptan Runnable como Tarea y tienen worker thread que ejecuta esas tareas.
Heredar todos los métodos de subproceso es una sobrecarga adicional solo para representar una Tarea que se puede hacer fácilmente con Runnable.
Cortesía de javarevisited.blogspot.com
Estas fueron algunas de las diferencias notables entre Thread y Runnable en Java, si conoce otras diferencias en Thread vs Runnable que por favor, compártalo a través de comentarios. Yo personalmente uso Runnable sobre hilo para este escenario y recomienda utilizar Runnable o interfaz llamable basado en su requisito.
Sin Embargo, la diferencia significativa es.
Cuando haces una clase extends Thread
, cada uno de tus subprocesos crea un objeto único y se asocia con él.
Cuando implements Runnable
, comparte el mismo objeto en varios subprocesos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-21 15:02:55
En realidad, no es sabio comparar Runnable
y Thread
entre sí.
Estos dos tienen una dependencia y relación en multi-threading al igual que Wheel and Engine
relación de vehículo de motor.
Yo diría que solo hay una forma de multi-threading con dos pasos. Déjame exponer mi punto.
Ejecutable:
Al implementar interface Runnable
significa que estás creando algo que está run able
en un hilo diferente. Ahora creando algo que puede funcionar dentro de un thread (ejecutable dentro de un hilo), no significa crear un hilo.
Así que la clase MyRunnable
no es más que una clase ordinaria con un método void run
.
Y sus objetos serán algunos objetos ordinarios con solo un método run
que se ejecutará normalmente cuando se llame. (a menos que pasemos el objeto en un hilo).
Hilo:class Thread
, Yo diría que una clase muy especial con la capacidad de iniciar un nuevo hilo que en realidad permite multi-threading a través de su start()
método.
¿Por qué no es sabio comparar?
Porque los necesitamos para multi-threading.
Para Multi-threading necesitamos dos cosas:
- Algo que se puede ejecutar dentro de un hilo (Ejecutable).
- Algo que puede iniciar un nuevo Hilo (Hilo).
Así que técnica y teóricamente ambos son necesarios para iniciar un subproceso, uno correrá y uno lo hará correr (Como Wheel and Engine
de motor vehículo).
Es por eso que no puedes iniciar un hilo con MyRunnable
necesitas pasarlo a una instancia de Thread
.
Pero es posible crear y ejecutar un hilo solo usando class Thread
porque la clase Thread
implementa Runnable
así que todos sabemos que Thread
también es un Runnable
dentro.
Finalmente Thread
y Runnable
se complementan entre sí para multihilo no competidor o reemplazo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-03 05:58:59
Debe implementar Runnable, pero si se está ejecutando en Java 5 o superior, no debe iniciarlo con new Thread
sino usar un ExecutorService en su lugar. Para más detalles vea: Cómo implementar el subproceso simple en Java.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:36
No soy un experto, pero se me ocurre una razón para implementar Runnable en lugar de extend Thread: Java solo admite herencia única, por lo que solo puede extender una clase.
Edit: Esto originalmente decía "Implementar una interfaz requiere menos recursos."también, pero necesitas crear una nueva instancia de subproceso de cualquier manera, así que esto estuvo mal.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-12 14:32:01
Yo diría que hay una tercera manera:
public class Something {
public void justAnotherMethod() { ... }
}
new Thread(new Runnable() {
public void run() {
instanceOfSomething.justAnotherMethod();
}
}).start();
Tal vez esto está influenciado un poco por mi reciente uso intensivo de Javascript y Actionscript 3, pero de esta manera su clase no necesita implementar una interfaz bastante vaga como Runnable
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-25 21:41:00
Con el lanzamiento de Java 8, ahora hay una tercera opción.
Runnable
es una interfaz funcional , lo que significa que las instancias de la misma se pueden crear con expresiones lambda o referencias de métodos.
Su ejemplo puede ser reemplazado por:
new Thread(() -> { /* Code here */ }).start()
O si desea utilizar un ExecutorService
y una referencia de método:
executor.execute(runner::run)
Estos no solo son mucho más cortos que sus ejemplos, sino que también vienen con muchas de las ventajas indicadas en otras respuestas de usar Runnable
sobre Thread
, como la responsabilidad individual y el uso de la composición porque no estás especializando el comportamiento del hilo. De esta manera también evita crear una clase extra si todo lo que necesita es un Runnable
como lo hace en sus ejemplos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-05 12:10:44
Crear una instancia de una interfaz da una separación más limpia entre su código y la implementación de subprocesos, por lo que preferiría implementar Runnable en este caso.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-12 14:33:09
- Java no admite herencia múltiple, lo que significa que solo puede extender una clase en Java, por lo que una vez que extendió la clase
Thread
perdió su oportunidad y no puede extender o heredar otra clase en Java. - En la programación orientada a objetos extender una clase generalmente significa agregar nueva funcionalidad, modificar o mejorar comportamientos. Si no estamos haciendo ninguna modificación en
Thread
entonces use la interfazRunnable
en su lugar. -
Runnable
interfaz representa unTask
que puede ser ejecutado porThread
oExecutors
o por cualquier otro medio. Así que la separación lógica deTask
comoRunnable
queThread
es una buena decisión de diseño. - Separar la tarea como
Runnable
significa que podemos reutilizar la tarea y también tenemos libertad para ejecutarla desde diferentes medios. Dado que no puede reiniciar unThread
una vez que se complete, nuevamenteRunnable
vsThread
para la tarea,Runnable
es el ganador. - Java designer reconoce esto y es por eso que
Executors
aceptaRunnable
comoTask
y tienen worker thread que ejecuta aquellos tarea. - Heredar todos los métodos
Thread
es una sobrecarga adicional solo para representar unTask
que se puede hacer fácilmente conRunnable
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-21 15:45:57
Ejecutable porque:
- Deja más flexibilidad para el Implementación ejecutable para extender otra clase
- Separa el código de ejecución
- le Permite ejecutar su ejecutable desde un grupo de subprocesos, el event thread, o de cualquier otra manera en futuro.
Incluso si usted no necesita nada de esto ahora, usted puede en el futuro. Dado que no hay ningún beneficio en sobreescribir el hilo, Runnable es una mejor solución.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-07 04:28:57
Todos aquí parecen pensar que implementar Runnable es el camino a seguir y realmente no estoy en desacuerdo con ellos, pero también hay un caso para extender el hilo en mi opinión, de hecho, lo has demostrado en tu código.
Si implementas Runnable entonces la clase que implementa Runnable no tiene control sobre el nombre del hilo, es el código de llamada el que puede establecer el nombre del hilo, así:
new Thread(myRunnable,"WhateverNameiFeelLike");
Pero si extiendes Thread entonces puedes manejar esto dentro de la clase en sí mismo (al igual que en tu ejemplo nombras el hilo 'ThreadB'). En este caso usted:
A) podría darle un nombre más útil para fines de depuración
B) están forzando que ese nombre se use para todas las instancias de esa clase (a menos que ignore el hecho de que es un hilo y haga lo anterior con él como si fuera un Ejecutable, pero estamos hablando de convención aquí en cualquier caso, así que puede ignorar esa posibilidad que siento).
Incluso podrías, por ejemplo, tomar un rastro de pila de su creación y usa eso como el nombre del hilo. Esto puede parecer extraño, pero dependiendo de cómo esté estructurado su código, puede ser muy útil para fines de depuración.
Esto puede parecer una cosa pequeña, pero donde tiene una aplicación muy compleja con una gran cantidad de hilos y, de repente, las cosas ' se han detenido '(ya sea por razones de bloqueo o posiblemente debido a un defecto en un protocolo de red que sería menos obvio - u otras razones interminables), a continuación, obtener un volcado de pila de Java donde todos los hilos se llaman 'Thread-1','Thread-2', 'Thread-3' no siempre es muy útil (depende de cómo se estructuran sus subprocesos y si puede decir útilmente cuál es cuál solo por su seguimiento de pila - no siempre es posible si está utilizando grupos de múltiples subprocesos todos corriendo el mismo código).
Dicho esto, por supuesto, también podría hacer lo anterior de una manera genérica creando una extensión de la clase thread que establezca su nombre en un rastro de pila de su llamada de creación y luego usarlo con sus implementaciones ejecutables en lugar de la clase de subproceso java estándar (ver a continuación), pero además del seguimiento de pila, podría haber más información específica del contexto que sería útil en el nombre del subproceso para la depuración (una referencia a una de las muchas colas o sockets que podría procesar, por ejemplo, en cuyo caso podría preferir extender el subproceso específicamente para ese caso para que pueda hacer que el compilador lo obligue (u otros que usen sus bibliotecas) a pasar cierta información (por ejemplo, la cola / socket en cuestión) para su uso en el nombre).
Aquí hay un ejemplo del subproceso genérico con la llamada stack trace como su nombre:
public class DebuggableThread extends Thread {
private static String getStackTrace(String name) {
Throwable t= new Throwable("DebuggableThread-"+name);
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
t.printStackTrace(ps);
return os.toString();
}
public DebuggableThread(String name) {
super(getStackTrace(name));
}
public static void main(String[] args) throws Exception {
System.out.println(new Thread());
System.out.println(new DebuggableThread("MainTest"));
}
}
Y aquí hay una muestra de la salida comparando los dos nombres:
Thread[Thread-1,5,main]
Thread[java.lang.Throwable: DebuggableThread-MainTest
at DebuggableThread.getStackTrace(DebuggableThread.java:6)
at DebuggableThread.<init>(DebuggableThread.java:14)
at DebuggableThread.main(DebuggableThread.java:19)
,5,main]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-19 23:12:49
Dado que este es un tema muy popular y las buenas respuestas se extienden por todas partes y se tratan en gran profundidad, sentí que es justificable compilar las buenas respuestas de los demás en una forma más concisa, para que los recién llegados tengan una visión general fácil por adelantado:
Por lo general, se extiende una clase para agregar o modificar la funcionalidad. Por lo tanto, si no quieres para sobrescribir cualquier comportamiento del hilo, entonces usa Runnable.
En la misma luz, si no necesita para heredar métodos de subproceso, puede prescindir de overhead usando Runnable.
Single inheritance : Si extiende Thread no puede extender desde ninguna otra clase, por lo que si eso es lo que necesita hacer, debe usar Runnable.
Es un buen diseño separar la lógica de dominio de los medios técnicos, en ese sentido es mejor tener una tarea ejecutable aislando su tarea de su runner .
Puede ejecutarel mismo objeto ejecutable varias veces, sin embargo, un objeto Thread solo se puede iniciar una vez. (Tal vez la razón, por qué los ejecutores aceptan Runnables, pero no Threads.)
Si desarrolla su tarea como Ejecutable, tiene toda la flexibilidad para usarla ahora y en el futuro. Puedes hacer que se ejecute simultáneamente a través de ejecutores, pero también a través de Subprocesos. Y aún así también podría usar / llamarlo no concurrentemente dentro del mismo hilo como cualquier otro tipo/objeto ordinario.
Esto también hace que sea más fácil separar los aspectos de lógica de tareas y concurrencia en sus pruebas unitarias .
Si está interesado en esta pregunta, también podría estar interesado en la diferencia entre Callable y Runnable.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:36
Esto se discute en el tutorial de Oracle Definiendo e iniciando un Hilo :
¿Cuál de estos modismos deberías usar? El primer idioma, que emplea un Objeto ejecutable, es más general, porque el objeto ejecutable puede subclase una clase distinta de Thread. El segundo idioma es más fácil de usar en aplicaciones simples, pero está limitado por el hecho de que su tarea la clase debe ser un descendiente de Thread. Esta lección se centra en la primera enfoque, que separa la Tarea ejecutable desde el objeto Thread que ejecuta la tarea. Este enfoque no solo es más flexible, sino que es aplicable a las API de gestión de subprocesos de alto nivel cubiertas tarde.
En otras palabras, implementar Runnable
funcionará en escenarios donde su clase extienda una clase que no sea Thread
. Java no admite herencia múltiple. Además, no será posible extender Thread
cuando se utilicen algunas de las API de gestión de subprocesos de alto nivel. El único escenario donde se extiende Thread
es preferible en una pequeña aplicación que no estará sujeta a actualizaciones en el futuro. Casi siempre es mejor implementar Runnable
ya que es más flexible a medida que su proyecto crece. Un cambio de diseño no tendrá un impacto importante, ya que puede implementar muchas interfaces en Java, pero solo extender una clase.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-21 16:44:09
Si no me equivoco, es más o menos similar a
¿Cuál es la diferencia entre una interfaz y una clase abstracta?
Extends establece " Es Una relación" y la interfaz proporciona " Tiene una capacidad".
Prefiere implements Runnable :
- Si no tienes que extender la clase Thread y modificar la implementación predeterminada de la API Thread
- Si estás ejecutando un fuego y olvidas la orden
- Si ya están extendiendo otra clase
Prefiere "extiende el Hilo" :
- Si tiene que anular cualquiera de estos métodos Thread como se indica en la página de documentación de oracle
Generalmente no es necesario anular el comportamiento del hilo. Así que implementa Runnable es preferible para la mayoría de las veces.
En una nota diferente, el uso de API avanzada ExecutorService
o ThreadPoolExecutorService
proporciona más flexibilidad y control.
Echa un vistazo a esta Pregunta SE:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:31
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-01 15:05:06
Separar la clase Thread de la implementación Ejecutable también evita posibles problemas de sincronización entre el thread y el método run (). Un Ejecutable separado generalmente da mayor flexibilidad en la forma en que se hace referencia y se ejecuta el código ejecutable.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-08 07:03:06
Una de las razones por las que desea implementar una interfaz en lugar de extender una clase base es que ya está extendiendo alguna otra clase. Solo puede extender una clase, pero puede implementar cualquier número de interfaces.
Si extiendes el subproceso, básicamente estás evitando que tu lógica sea ejecutada por cualquier otro subproceso que no sea 'this'. Si solo quieres algún subproceso para ejecutar tu lógica, es mejor simplemente implementar Runnable.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-25 17:29:00
Si usas runnable puedes ahorrar espacio para extenderlo a cualquiera de tus otras clases.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-26 05:58:02
¿Podemos volver a visitar la razón básica por la que queríamos que nuestra clase se comportara como un Thread
?
No hay ninguna razón en absoluto, solo queríamos ejecutar una tarea, lo más probable en un modo asíncrono, lo que significa precisamente que la ejecución de la tarea debe ramificarse desde nuestro hilo principal y el hilo principal si termina temprano, puede o no puede esperar la ruta ramificada(tarea).
Si este es todo el propósito, entonces dónde veo la necesidad de un Hilo especializado. Esto se puede lograr recogiendo un CRUDO Thread del Grupo de subprocesos del Sistema y asignándole nuestra tarea (puede ser una instancia de nuestra clase) y eso es todo.
Así que obedezcamos el concepto OOPs y escribamos una clase del tipo que necesitamos. Hay muchas maneras de hacer las cosas, hacerlo de la manera correcta importa.
Necesitamos una tarea, así que escriba una definición de tarea que se pueda ejecutar en un Subproceso. Así que usa Runnable.
Siempre recuerde que implements
se usa especialmente para impartir un comportamiento y extends
se usa para impartir un característica / propiedad.
No queremos la propiedad del hilo, sino que queremos que nuestra clase se comporte como una tarea que se puede ejecutar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-22 03:11:51
Sí, Si llama a ThreadA call, entonces no necesita llamar al método start y el método run es llamar después de llamar a la clase ThreadA solamente. Pero si usa la llamada ThreadB, entonces necesita el hilo de inicio necesario para el método call run. Si tienes más ayuda, contéstame.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-28 08:31:16
Creo que es más útil usar Runnable por todas las razones mencionadas, pero a veces me gusta extender el Hilo para poder crear mi propio método de detención de hilo y llamarlo directamente en el hilo que he creado.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-09 19:09:15
Java no admite herencia múltiple, por lo que si extiende la clase Thread, no se extenderá ninguna otra clase.
Por ejemplo: Si crea un applet, entonces debe extender la clase Applet, así que aquí la única manera de crear un subproceso es implementando la interfaz ejecutable
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-09 19:28:31
Ese es el S de SÓLIDO: Responsabilidad única.
Un thread encarna el contexto en ejecución (como en el contexto de ejecución: marco de pila, id de hilo, etc.) de la ejecución asíncrona de un fragmento de código. Esa pieza de código idealmente debería ser la misma implementación, ya sea síncrona o asíncrona.
Si los agrupa en una implementación, le da al objeto resultante dos no relacionados causas de cambio:
- manejo de subprocesos en su aplicación (es decir. consulta y modificación del contexto de ejecución)
- algoritmo implementado por la pieza de código (la parte ejecutable)
Si el lenguaje que usa admite clases parciales o herencia múltiple, entonces puede segregar cada causa en su propia superclase, pero se reduce a lo mismo que componer los dos objetos, ya que sus conjuntos de características no se superponen. Eso es por la teoría.
En la práctica, en términos generales, un programa no necesita llevar más complejidad de la necesaria. Si tiene un subproceso trabajando en una tarea específica, sin cambiar esa tarea, probablemente no tenga sentido hacer que las tareas separen clases, y su código siga siendo más simple.
En el contexto de Java , dado que la instalación ya está , probablemente sea más fácil comenzar directamente con las clases independientes Runnable
, y pasar sus instancias a Thread
(o Executor
) instancias. Una vez que utiliza para ese patrón, no es más difícil de usar (o incluso leer) que el simple caso de hilo ejecutable.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-11 08:41:39
Diferencia entre Hilo y ejecutable .Si estamos creando un hilo usando la clase Thread, entonces el número de hilo es igual al número de objeto que creamos . Si estamos creando thread implementando la interfaz ejecutable, entonces podemos usar un solo objeto para crear múltiples thread.So un único objeto es compartido por varios Thread.So tomará menos memoria
Así que dependiendo del requisito si nuestros datos no son sensibles. Por lo que se puede compartir entre varios Subprocesos podemos utilizar Runnable interfaz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-05 06:13:58
Añadiendo mis dos centavos aquí -
Siempre que sea posible use implements Runnable
. A continuación se presentan dos advertencias sobre por qué no debe usar
extends Thread
s
-
Lo ideal es que nunca se extienda la clase Thread; la clase
Thread
debe hacersefinal
. Al menos sus métodos comothread.getId()
. Ver esta discusión para un error relacionado con la extensión deThread
s. Aquellos que les gusta resolver puzzles pueden ver otro efecto secundario de extender el hilo. El siguiente código se imprimirá inalcanzable código cuando nadie les está notificando.
Véase http://pastebin.com/BjKNNs2G .
public class WaitPuzzle {
public static void main(String[] args) throws InterruptedException {
DoNothing doNothing = new DoNothing();
new WaitForever(doNothing).start();
new WaitForever(doNothing).start();
new WaitForever(doNothing).start();
Thread.sleep(100);
doNothing.start();
while(true) {
Thread.sleep(10);
}
}
static class WaitForever extends Thread {
private DoNothing doNothing;
public WaitForever(DoNothing doNothing) {
this.doNothing = doNothing;
}
@Override
public void run() {
synchronized (doNothing) {
try {
doNothing.wait(); // will wait forever here as nobody notifies here
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Unreachable Code");
}
}
}
static class DoNothing extends Thread {
@Override
public void run() {
System.out.println("Do Nothing ");
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-03 09:41:19
Una diferencia entre implementar Runnable y extender Thread es que al extender Thread, cada uno de tus threads tiene un objeto único asociado, mientras que implementar Runnable, muchos threads pueden compartir la misma instancia de objeto.
Una clase que implementa Runnable no es un subproceso sino solo una clase. Para que un Ejecutable sea ejecutado por un Subproceso, debe crear una instancia de Subproceso y pasar la instancia Ejecutable como destino.
En la mayoría de los casos, el ejecutable la interfaz debe ser usada si solo estás planeando sobreescribir el método run () y ningún otro método Thread. Esto es importante porque las clases no deben ser subclases a menos que el programador tenga la intención de modificar o mejorar el comportamiento fundamental de la clase.
Cuando es necesario extender una superclase, implementar la interfaz Ejecutable es más apropiado que usar la clase Thread. Porque podemos extender otra clase mientras implementamos una interfaz ejecutable para hacer un subproceso. Pero si solo extendemos la clase Thread no podemos heredar de ninguna otra clase.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-03 13:46:02