Observemos algunas otras diferencias entre Thread y Runnable con la ayuda del cuadro de comparación que se muestra a continuación:
Gráfica comparativa
Bases para la comparación | Hilo | Ejecutable |
---|---|---|
BASIC | Cada hilo crea un objeto único y se asocia con él. | Varios hilos comparten los mismos objetos. |
Memoria | Como cada hilo crea un objeto único, se requiere más memoria. | Como varios subprocesos comparten el mismo objeto, se utiliza menos memoria. |
Extensible | En Java, la herencia múltiple no está permitida, por lo tanto, después de que una clase extiende la clase Thread, no puede extender ninguna otra clase. | Si una clase define un subproceso que implementa la interfaz Runnable, tiene la posibilidad de extender una clase. |
Utilizar | Un usuario debe extender la clase de subproceso solo si desea anular los otros métodos en la clase de subproceso. | Si solo desea especializar el método de ejecución, entonces implementar Runnable es una mejor opción. |
Acoplamiento | La clase Thread extendida introduce un acoplamiento estrecho ya que la clase contiene el código de la clase Thread y también el trabajo asignado al hilo | La implementación de la interfaz Runnable introduce un acoplamiento suelto, ya que el código de Thread está separado del trabajo de Threads. |
Definición de la clase de hilo
El hilo es una clase en el paquete java.lang . La clase Thread extiende una clase Object, e implementa interfaces Runnable . La clase Thread tiene constructores y métodos para crear y operar en el hilo. Cuando creamos varios subprocesos, cada subproceso crea un objeto único y se asocia con ese objeto. Si creas un subproceso extendiendo la clase Thread, además no puedes extender ninguna otra clase ya que java no admite herencia múltiple. Por lo tanto, debe elegir extender la clase Thread solo cuando también desea anular algunos otros métodos de la clase Thread. Veamos un ejemplo de cómo crear un hilo extendiendo una clase Thread.
/ * La definición de un hilo * / Class Mythread extiende el subproceso {/ * trabajo del hilo * / public void run () {for (int i = 0; i <10; i ++) {System.Out.Println ("Child Thread" ); }} Clase mainThread {/ * trabajo del hilo principal * / public static void main (String args []) {Mythread mt = new Mythread (); / * el subproceso principal creó el subproceso secundario * / mt.start (); para (int i = 0; i <10; i ++) {System.Out.Print ("Tema principal"); }}} / * Salida * / Hilo principal Hilo principal Hilo principal Hilo principal Hilo infantil Hilo infantil Hilo infantil Hilo infantil Hilo principal Hilo infantil Hilo principal Hilo principal Hilo infantil Hilo infantil Hilo principal Hilo principal Hilo infantil Hilo infantil Hilo principal
En el código anterior, creo una clase Mythread que extiende la clase Thread y reemplaza un método de ejecución de la clase Thread. En la clase que contiene el método principal, creo un objeto de subproceso (mt) de la clase Mythread y utilizando el objeto de subproceso invocado el método start (). El método de inicio inicia la ejecución del hilo y, al mismo tiempo, JVM invoca el método de ejecución del hilo. Ahora hay dos subprocesos en el programa, uno principal y segundo secundario creado por el hilo principal. La ejecución de ambos subprocesos ocurre simultáneamente, pero no se puede fingir la salida exacta.
Definición de interfaz ejecutable
Runnable es una interfaz en el paquete java.lang . Implementando la interfaz Runnable podemos definir un hilo. La interfaz Runnable tiene un solo método run (), que es implementado por la clase que implementa la interfaz Runnable. Cuando elige definir un hilo que implementa una interfaz Runnable, todavía tiene la opción de extender cualquier otra clase. Cuando crea varios subprocesos implementando la interfaz Runnable, cada subproceso comparte la misma instancia ejecutable. aprendamos cómo definir un hilo usando la interfaz Runnable.
/ * Definiendo un hilo * / La clase Runnablethread implementa el trabajo {/ * ejecutable del hilo * / public void run () {for (int i = 0; i <10; i ++) {System.Out.Println ("Child Thread" ); }} Clase mainThread {/ * trabajo del hilo principal * / public static void main (String args []) {Mythread rt = new Mythread (); / * el hilo principal creó el objeto ejecutable * / Thread t = new Thread (rt); / * el hilo principal crea un hilo secundario y pasa el objeto ejecutable * / t.start (); para (int i = 0; i <10; i ++) {System.Out.Print ("Tema principal"); }}} / * Salida * / Hilo principal Hilo principal Hilo principal Hilo principal Hilo infantil Hilo infantil Hilo infantil Hilo infantil Hilo principal Hilo infantil Hilo principal Hilo principal Hilo infantil Hilo infantil Hilo principal Hilo principal Hilo infantil Hilo infantil Hilo principal
En el código anterior, creé una clase Runnablethread que implementa la interfaz Runnable y define el trabajo del hilo al implementar el método run () de la interfaz Runnable. Luego creo un mainthread de clase que contiene el método main. Dentro del método principal, declaré un objeto ejecutable de la clase Runnablethread y pasé este objeto al constructor del subproceso mientras declaraba un subproceso. De esta manera, vinculé el objeto de hilo (t) con un objeto ejecutable (rt). Luego, el objeto de subproceso invoca el método de inicio del subproceso que invoca aún más el método de ejecución de la clase Runnablethread. Si no hubiera vinculado el objeto ejecutable con el objeto Thread, el método start de threads habría invocado el método run de la clase Thread. Ahora, nuevamente, hay dos subprocesos en el código, el principal y el principal crean un subproceso secundario que se ejecutan simultáneamente, pero nunca se puede fingir el resultado exacto.
Diferencias clave entre Thread y Runnable en Java
- Cada hilo creado al extender la clase Thread crea un objeto único para él y se asocia con ese objeto. Por otro lado, cada subproceso creado al implementar una interfaz ejecutable comparte la misma instancia ejecutable.
- Como cada subproceso está asociado con un objeto único cuando se crea al extender la clase Thread, se requiere más memoria. Por otro lado, cada subproceso creado al implementar la interfaz Runnable comparte el mismo espacio de objeto, por lo tanto, requiere menos memoria.
- Si amplía la clase Thread, puede heredar cualquier otra clase ya que Java no permite la herencia múltiple, mientras que la implementación de Runnable aún ofrece la posibilidad de que una clase herede cualquier otra clase.
- Uno debe extender una clase Thread solo si tiene que anular o especializar algunos otros métodos de la clase Thread. Debe implementar una interfaz Ejecutable si solo desea especializar el método de ejecución.
- La extensión de la clase Thread introduce un acoplamiento estricto en el código, ya que el código de Thread y el trabajo de thread están contenidos en la misma clase. Por otro lado, la interfaz de ejecución ejecutable introduce un acoplamiento suelto en el código, ya que el código del subproceso está separado del trabajo asignado al subproceso.
Conclusión:
Es preferible implementar una interfaz Runnable en lugar de extender la clase Thread. A medida que se implementa Runnable, su código se acopla libremente ya que el código del hilo es diferente de la clase que asigna el trabajo al hilo. Requiere menos memoria y también permite que una clase herede cualquier otra clase.