Puesto que el uso ExecutorService
puede submit
una tarea Callable
y devolver una Future
, ¿por qué tenga que utilizar para envolver FutureTask
Callable
tarea y utilizar el método execute
? Siento que ambos hacen lo mismo.¿Cuál es la diferencia entre Future y FutureTask en Java?
Respuesta
De hecho, tiene razón. Los dos enfoques son idénticos. Por lo general, no es necesario que los envuelva usted mismo. Si es así, es muy probable duplicando el código en AbstractExecutorService:
/**
* Returns a <tt>RunnableFuture</tt> for the given callable task.
*
* @param callable the callable task being wrapped
* @return a <tt>RunnableFuture</tt> which when run will call the
* underlying callable and which, as a <tt>Future</tt>, will yield
* the callable's result as its result and provide for
* cancellation of the underlying task.
* @since 1.6
*/
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
La única diferencia entre el futuro y RunnableFuture, es el método run():
/**
* A {@link Future} that is {@link Runnable}. Successful execution of
* the <tt>run</tt> method causes completion of the <tt>Future</tt>
* and allows access to its results.
* @see FutureTask
* @see Executor
* @since 1.6
* @author Doug Lea
* @param <V> The result type returned by this Future's <tt>get</tt> method
*/
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
Una buena razón para dejar que el Ejecutor construir el FutureTask para usted es asegurarse de que no haya manera posible de que exista más de una referencia a la instancia FutureTask. Es decir, el Ejecutor posee esta instancia.
Future
es solo una interfaz. Detrás de la escena, la implementación es FutureTask
.
Puede usar completamente FutureTask
manualmente, pero perderá las ventajas de usar Executor
(agrupamiento de hilo, limitar el hilo, etc.). El uso de FutureTask
es bastante similar al uso del antiguo Thread
y el ejecuta el método.
FutureTask implementa Future
Solo necesitaría utilizar FutureTask si desea cambiar su comportamiento o acceder a su Callable más adelante. Para el 99% de los usos, solo use Callable y Future.
FutureTask Esta clase proporciona una base implementation of Future
, con métodos para iniciar y cancelar un cálculo
Future es la interfaz
como Mark y otros, respondió correctamente que Future
es la interfaz para FutureTask
y Executor
efectiva su fábrica; lo que significa que el código de la aplicación rara vez instancia FutureTask
directamente. Para complementar la discusión que estoy proporcionando un ejemplo que muestra una situación en la FutureTask
se construye y se usa directamente, fuera de cualquier Executor
:
FutureTask<Integer> task = new FutureTask<Integer>(()-> {
System.out.println("Pretend that something complicated is computed");
Thread.sleep(1000);
return 42;
});
Thread t1 = new Thread(()->{
try {
int r = task.get();
System.out.println("Result is " + r);
} catch (InterruptedException | ExecutionException e) {}
});
Thread t2 = new Thread(()->{
try {
int r = task.get();
System.out.println("Result is " + r);
} catch (InterruptedException | ExecutionException e) {}
});
Thread t3 = new Thread(()->{
try {
int r = task.get();
System.out.println("Result is " + r);
} catch (InterruptedException | ExecutionException e) {}
});
System.out.println("Several threads are going to wait until computations is ready");
t1.start();
t2.start();
t3.start();
task.run(); // let the main thread to compute the value
Aquí, FutureTask
se utiliza como una herramienta de sincronización, como CountdownLatch
o barrera similar primitivo. Se podría haber reimplementado usando CountdownLatch
o bloqueos y condiciones; FutureTask
simplemente lo hace muy bien encapsulado, autoexplicativo, elegante y con menos código.
También tenga en cuenta que el método FutureTask # run() debe invocarse explícitamente en cualquiera de los hilos; no hay ningún ejecutor a tu alrededor que lo haga por ti. En mi código, es eventualmente ejecutado por el hilo principal, pero se puede modificar el método get()
para llamar al run()
en el primer hilo llamando al get()
, por lo tanto, el primer hilo que alcance get()
, y cualquiera de T1, T2 o T3, podría el cálculo para todos los hilos restantes.
En esta idea, el primer resultado de la solicitud de subprocesos haría el cálculo para otros, mientras que los intentos concurrentes serían bloqueados, es Memoizer basado, consulte Ejemplo de memoria caché de memoria de la página 108 en "Simultaneidad de Java en la práctica".
- 1. ¿Cuál es la diferencia entre referencias y objetos en Java?
- 2. ¿Cuál es la diferencia entre a.getClass() y A.class en Java?
- 3. ¿Cuál es la diferencia entre interfaz y @interface en java?
- 4. ¿Cuál es la diferencia entre booleano y booleano en Java?
- 5. ¿Cuál es la diferencia entre? y Object en genéricos Java?
- 6. ¿Cuál es la diferencia entre int.class y Integer.TYPE en java?
- 7. ¿Cuál es la diferencia entre Boolean.TRUE y true en Java?
- 8. ¿Cuál es la diferencia entre Collection y List en Java?
- 9. ¿Cuál es la diferencia entre + = y = +?
- 10. ¿Se puede usar objetos Future/Futuretask con Spring TaskExecutors?
- 11. ¿Cuál es la diferencia entre Java RMI y RPC?
- 12. ¿Cuál es la diferencia entre Java RMI y JMS?
- 13. Java: ¿Cuál es la diferencia entre autoboxing y casting?
- 14. ¿Cuál es la diferencia entre java y jsp?
- 15. ¿Cuál es la diferencia entre scala @Serializable y Java Serializable?
- 16. ¿Cuál es la diferencia entre Java 1.6 y 1.7 jarsigner
- 17. ¿Cuál es la diferencia entre JavaScript y Java?
- 18. ¿cuál es la diferencia entre:.! y: r !?
- 19. ¿Cuál es la diferencia entre ".equals" y "=="?
- 20. Cuál es la diferencia entre $ y jQuery
- 21. Cuál es la diferencia entre = y: =
- 22. Cuál es la diferencia entre $ (...) y `...`
- 23. ¿Cuál es la diferencia entre dict() y {}?
- 24. ¿Cuál es la diferencia entre [indefinido] y [,]?
- 25. ¿Cuál es la diferencia entre {0} y ""?
- 26. ¿Cuál es la diferencia entre .ToString (+) y ""
- 27. ¿Cuál es la diferencia entre `##` y `hashCode`?
- 28. ¿Cuál es la diferencia entre "$^N" y "$ +"?
- 29. ¿Cuál es la diferencia entre " " y ""?
- 30. ¿Cuál es la diferencia entre la abstracción y la encapsulación?
FutureTask.get() nunca lanza una CancellationException, mientras que Future.get() sí lo hace. ¿Es esto correcto? Consulte http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/FutureTask.html#get(long, java.util.concurrent.TimeUnit). –