La diferencia entre las interfaces Ejecutables y Ejecutables en Java


¿Cuál es la diferencia entre usar las interfaces Runnable y Callable al diseñar un subproceso concurrente en Java, por qué elegirías uno sobre el otro?

Author: Mike B., 2008-09-26

11 answers

Ver explicación aquí.

La interfaz llamable es similar a Runnable, en que ambos están diseñados para clases cuyas instancias son potencialmente ejecutado por otro hilo. Un Ejecutable, sin embargo, no devuelve un resultado y no puede lanzar un excepción marcada.

 386
Author: Jorge Ferreira,
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-06-09 11:10:05

¿cuáles son las diferencias en las aplicaciones de Runnable y Callable. ¿La diferencia solo está presente con el parámetro return en Callable?

, Básicamente, sí. Ver las respuestas a esta pregunta. Y el javadoc para Callable.

¿Cuál es la necesidad de tener ambos si Callable puede hacer todo lo que Runnable hace?

Porque la interfaz Runnable no puede hacer todo lo que Callable hace!

Runnable ha existido desde Java 1.0, pero Callable solo se introdujo en Java 1.5 ... para manejar casos de uso que Runnable no soporta. En teoría, el equipo de Java podría haber cambiado la firma del método Runnable.run(), pero esto habría roto la compatibilidad binaria con el código pre-1.5, requiriendo recodificación al migrar código Java antiguo a JVM más recientes. Eso es UN GRAN NO-NO. Java se esfuerza por ser compatible con versiones anteriores ... y ese ha sido uno de los mayores puntos de venta de Java para la computación empresarial.

Y, obviamente, hay casos de uso en los que una tarea no necesita para devolver un resultado o lanzar una excepción marcada. Para esos casos de uso, usar Runnable es más conciso que usar Callable<Void> y devolver un valor ficticio (null) del método call().

 234
Author: Stephen C,
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:02:48
  • A Callable necesita implementar el método call() mientras que a Runnable necesita implementar el método run().
  • A Callable puede devolver un valor pero a Runnable no puede.
  • Un Callable puede lanzar una excepción marcada, pero un Runnable no puede.
  • A Callable se puede usar con los métodos ExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks) pero a Runnable no se puede usar.

    public interface Runnable {
        void run();
    }
    
    public interface Callable<V> {
        V call() throws Exception;
    }
    
 70
Author: nikli,
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-09-02 11:50:25

Encontré esto en otro blog que puede explicar un poco más estas diferencias :

Aunque ambas interfaces son implementadas por las clases que desean ejecutar en un hilo de ejecución diferente, pero hay pocas diferencias entre las dos interfaces que son:

  • Una instancia Callable<V> devuelve un resultado de tipo V, mientras que una instancia Runnable no lo hace.
  • Una instancia Callable<V> puede lanzar excepciones verificadas, mientras que una instancia Runnable no puede

Los diseñadores de Java sintieron la necesidad de ampliar las capacidades de la interfaz Runnable, pero no querían afectar los usos de la interfaz Runnable y probablemente esa fue la razón por la que optaron por tener una interfaz separada llamada Callable en Java 1.5 que cambiar la ya existente Runnable.

 35
Author: amoran,
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-04-13 14:46:01

Veamos dónde se usaría Runnable y Callable.

Tanto Runnable como Callable se ejecutan en un hilo diferente al hilo que llama. Pero Callable puede devolver un valor y Runnable no puede. Entonces, ¿dónde se aplica esto realmente?

Runnable : Si tienes una tarea fire y forget, usa Runnable. Ponga su código dentro de un Ejecutable y cuando se llame al método run (), podrá realizar su tarea. El hilo de llamada realmente no le importa cuando realice su tarea.

Callable : Si está intentando recuperar un valor de una tarea, utilice Callable. Ahora llamable por sí solo no hará el trabajo. Usted necesitará un futuro que se envuelve alrededor de su Callable y obtener sus valores en el futuro.conseguir (). Aquí el hilo que llama será bloqueado hasta que el Futuro regrese con resultados que a su vez está esperando que el método callable() se ejecute.

Así que piense en una interfaz para una clase de destino donde tiene tanto Ejecutable como llamable métodos empaquetados definidos. La clase de llamada llamará aleatoriamente a los métodos de la interfaz sin saber cuál se puede ejecutar y cuál se puede llamar. Los métodos ejecutables se ejecutarán de forma asíncrona, hasta que se llame a un método ejecutable. Aquí el hilo de la clase que llama se bloqueará ya que está recuperando valores de su clase de destino.

NOTA: Dentro de su clase de destino puede hacer las llamadas a Callable y Runnable en un solo ejecutor de subprocesos, haciendo que este mecanismo sea similar a un envío serie cola. Así que mientras la persona que llama llama a sus métodos empaquetados ejecutables el hilo de llamada se ejecutará muy rápido sin bloqueo. Tan pronto como llame a un método callable envuelto en el futuro tendrá que bloquear hasta que se ejecuten todos los demás elementos en cola. Solo entonces el método regresará con valores. Este es un mecanismo de sincronización.

 24
Author: Kris Subramanian,
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-12-16 23:18:55

Callable interfaz declara call() método y necesita proporcionar genéricos como tipo de Objeto call () debe devolver -

public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

Runnable por otro lado está la interfaz que declara el método run() al que se llama cuando se crea un Subproceso con el ejecutable y se llama a start() en él. También puedes llamar directamente a run () pero eso solo ejecuta el método run () es el mismo hilo.

public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used 
     * to create a thread, starting the thread causes the object's 
     * <code>run</code> method to be called in that separately executing 
     * thread. 
     * <p>
     * The general contract of the method <code>run</code> is that it may 
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

Para resumir pocas diferencias notables son

  1. Un objeto Runnable no devuelve un resultado mientras que un objeto Callable devuelve un resultado.
  2. Un objeto Runnable no puede lanzar una excepción marcada mientras que un objeto Callable puede lanzar una salvedad.
  3. La interfaz Runnable ha existido desde Java 1.0, mientras que Callable solo se introdujo en Java 1.5.

Algunas similitudes incluyen

  1. Las instancias de las clases que implementan interfaces ejecutables o llamables son potencialmente ejecutado por otro hilo.
  2. Instancia de interfaces tanto llamables como Ejecutables puede ser ejecutado por ExecutorService a través del método submit ().
  3. Ambas son interfaces funcionales y se pueden usar en expresiones Lambda desde Java8.

Los métodos en la interfaz ExecutorService son

<T> Future<T> submit(Callable<T> task);
Future<?> submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);
 14
Author: Aniket Thakur,
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-01-28 21:11:43

Propósito de estas interfaces de la documentación de oracle :

La interfaz Runnable debe ser implementada por cualquier clase cuyas instancias estén destinadas a ser ejecutadas por un Thread. La clase debe definir un método sin argumentos llamado run.

Callable : Una tarea que devuelve un resultado y puede lanzar una excepción. Los implementadores definen un único método sin argumentos llamados call. La interfaz Callable es similar a Runnable, ya que ambas están diseñadas para clases cuyas instancias son potencialmente ejecutadas por otro subproceso. Un Runnable, sin embargo, no devuelve un resultado y no puede lanzar una excepción marcada.

Otras diferencias:

  1. Puedes pasar Runnable para crear un Hilo . Pero no puedes crear un nuevo hilo pasando Callable como parámetro. Puede pasar solo a instancias de ExecutorService.

    Ejemplo:

    public class HelloRunnable implements Runnable {
    
        public void run() {
            System.out.println("Hello from a thread!");
        }   
    
        public static void main(String args[]) {
            (new Thread(new HelloRunnable())).start();
        }
    
    }
    
  2. Use Runnable para disparar y olvidar llamadas. Use Callable para verificar la resultado.

  3. Callable se puede pasar al método invokeAll a diferencia de Runnable. Los métodos invokeAny y invokeAll realizan las formas más comúnmente útiles de ejecución masiva, ejecutando una colección de tareas y luego esperando que al menos una, o todas, se completen

  4. Diferencia trivial: nombre del método a implementar = > run() para Runnable y call() para Callable.

 13
Author: Ravindra babu,
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
2018-01-22 18:17:14

Como ya se mencionó aquí, Callable es una interfaz relativamente nueva y se introdujo como parte del paquete de concurrencia. Tanto Callable como Runnable se pueden usar con ejecutores. Class Thread (que implementa Runnable en sí mismo) solo admite Runnable.

Todavía se puede usar Runnable con ejecutores. La ventaja de Callable es que puede enviarlo al ejecutor e inmediatamente recuperar el resultado futuro que se actualizará cuando finalice la ejecución. El mismo puede ser implementado con Ejecutable, pero en este caso tienes que gestionar los resultados tú mismo. Por ejemplo, puede crear una cola de resultados que contenga todos los resultados. Otro hilo puede esperar en esta cola y tratar con los resultados que llegan.

 9
Author: AlexR,
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-17 07:16:09
+-------------------------------------+--------------------------------------------------------------------------------------------------+
|              Runnable               |                                           Callable<T>                                            |
+-------------------------------------+--------------------------------------------------------------------------------------------------+
| Introduced in Java 1.0 of java.lang | Introduced in Java 1.5 of java.util.concurrent library                                           |
| Runnable cannot be parametrized     | Callable is a parametrized type whose type parameter indicates the return type of its run method |
| Runnable has run() method           | Callable has call() method                                                                       |
| Runnable.run() returns void         | Callable.call() returns a value of Type T                                                        |
| Can not throw Checked Exceptions    | Can throw Checked Exceptions                                                                     |
+-------------------------------------+--------------------------------------------------------------------------------------------------+

Los diseñadores de Java sintieron la necesidad de ampliar las capacidades de la interfaz Runnable, pero no querían afectar los usos de la interfaz Runnable y probablemente esa fue la razón por la que optaron por tener una interfaz separada llamada Callable en Java 1.5 que cambiar la interfaz ya existente Runnable que ha sido parte de Java desde Java 1.0. fuente

 4
Author: Premraj,
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-08 22:43:00

Las diferencias entre Callable y Runnable son las siguientes:

  1. Callable se introduce en JDK 5.0 pero Runnable se introduce en JDK 1.0
  2. Callable tiene el método call() pero Runnable tiene el método run ().
  3. Callable tiene un método de llamada que devuelve un valor, pero Runnable tiene un método de ejecución que no devuelve ningún valor.
  4. el método de llamada puede lanzar la excepción marcada, pero el método de ejecución no puede lanzar la excepción marcada.
  5. Se puede llamar usando el método submit () para poner en la tarea cola pero ejecutable use el método execute () para poner en la cola de tareas.
 3
Author: Raman Gupta,
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
2018-04-06 14:07:29

Interfaz pública ejecutable: La interfaz Ejecutable debe ser implementada por cualquier clase cuyas instancias estén destinadas a ser ejecutadas por un subproceso. La clase debe definir un método sin argumentos llamado run. Esta interfaz está diseñada para proporcionar un protocolo común para los objetos que desean ejecutar código mientras están activos. Por ejemplo, Runnable es implementado por la clase Thread. Estar activo simplemente significa que un hilo se ha iniciado y aún no se ha detenido.

En además, Runnable proporciona los medios para que una clase esté activa mientras no subclase el hilo. Una clase que implementa Runnable puede ejecutarse sin subclasificar Subprocesos instanciando una instancia de subproceso y pasándose a sí misma 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 Thread. Esto es importante porque las clases no deben ser subclases a menos que el programador tenga la intención de modificar o mejorar la comportamiento fundamental de la clase.

Desde: JDK1. 0


Interfaz pública llamable:

Una tarea que devuelve un resultado y puede lanzar una excepción. Los implementadores definen un único método sin argumentos llamados call. La interfaz Llamable es similar a Runnable, ya que ambas están diseñadas para clases cuyas instancias son potencialmente ejecutadas por otro subproceso. Un ejecutable, sin embargo, no devuelve un resultado y no puede lanzar una excepción marcada.

El La clase Executors contiene métodos de utilidad para convertir de otras formas comunes a clases llamables.

Desde: JDK 1.5

 2
Author: Srinivasulu Chinna,
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
2018-07-20 05:27:51