ejecutar: Se usa para activar y olvidar las llamadas
presentar: Se usa para inspeccionar el resultado de la llamada al método y tomar las acciones apropiadas sobre Future
objetado devuelto por la llamada
De javadocs
submit(Callable<T> task)
Envía una tarea de devolución de valor para su ejecución y devuelve un futuro que representa los resultados pendientes de la tarea.
Future<?> submit(Runnable task)
envía una tarea Ejecutable para su ejecución y devuelve un futuro que representa que tarea.
void execute(Runnable command)
ejecuta el comando dado en algún momento en el futuro. El comando puede ejecutarse en un nuevo hilo, en un hilo agrupado o en el hilo de llamada, a discreción de la implementación del Ejecutor.
Debe tener precaución al usar submit()
. Oculta la excepción en el marco a menos que incruste su código de tarea en el bloque try{} catch{}
.
Código de ejemplo: Este código se traga Arithmetic exception :/by zero
.
import java.util.concurrent.*;
import java.util.*;
public class ExecuteSubmitDemo{
public ExecuteSubmitDemo()
{
System.out.println("creating service");
ExecutorService service = Executors.newFixedThreadPool(10);
//ExtendedExecutor service = new ExtendedExecutor();
service.submit(new Runnable(){
public void run(){
int a=4, b = 0;
System.out.println("a and b="+a+":"+b);
System.out.println("a/b:"+(a/b));
System.out.println("Thread Name in Runnable after divide by zero:"+Thread.currentThread().getName());
}
});
service.shutdown();
}
public static void main(String args[]){
ExecuteSubmitDemo demo = new ExecuteSubmitDemo();
}
}
salida:
java ExecuteSubmitDemo
creating service
a and b=4:0
mismo código lanza mediante la sustitución de submit()
con execute
():
Reemplazar
service.submit(new Runnable(){
con
service.execute(new Runnable(){
de salida:
java ExecuteSubmitDemo
creating service
a and b=4:0
Exception in thread "pool-1-thread-1" java.lang.ArithmeticException:/by zero
at ExecuteSubmitDemo$1.run(ExecuteSubmitDemo.java:14)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
cómo manejar la este tipo de escenarios durante el uso de presentar()?
- Insertar el código de tareas (De cualquier Ejecutable o rescatable aplicación) con try {} catch {código de bloque}
- Implementar
CustomThreadPoolExecutor
Nueva solución:
import java.util.concurrent.*;
import java.util.*;
public class ExecuteSubmitDemo{
public ExecuteSubmitDemo()
{
System.out.println("creating service");
//ExecutorService service = Executors.newFixedThreadPool(10);
ExtendedExecutor service = new ExtendedExecutor();
service.submit(new Runnable(){
public void run(){
int a=4, b = 0;
System.out.println("a and b="+a+":"+b);
System.out.println("a/b:"+(a/b));
System.out.println("Thread Name in Runnable after divide by zero:"+Thread.currentThread().getName());
}
});
service.shutdown();
}
public static void main(String args[]){
ExecuteSubmitDemo demo = new ExecuteSubmitDemo();
}
}
class ExtendedExecutor extends ThreadPoolExecutor {
public ExtendedExecutor() {
super(1,1,60,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(100));
}
// ...
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (t == null && r instanceof Future<?>) {
try {
Object result = ((Future<?>) r).get();
} catch (CancellationException ce) {
t = ce;
} catch (ExecutionException ee) {
t = ee.getCause();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // ignore/reset
}
}
if (t != null)
System.out.println(t);
}
}
salida:
java ExecuteSubmitDemo
creating service
a and b=4:0
java.lang.ArithmeticException:/by zero
Tenga en cuenta que este comportamiento no está garantizado, ya que depende de si su 'Runnable' se ajusta o no a una 'Tarea', sobre la que puede no tener control. Por ejemplo, si su 'Ejecutor' es en realidad un' ScheduledExecutorService', su tarea se envolverá internamente en un 'Future' y uncaught' Throwable's estará vinculado a este objeto. – rxg
Quiero decir 'envuelto en un' Futuro 'o no', por supuesto. Consulte el Javadoc para [ScheduledThreadPoolExecutor # execute] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html#execute (java.lang.Runnable)), por ejemplo . – rxg