执行:用它发射后不管的调用
提交:用它来检查方法调用的结果并采取Future
适当行动反对通过调用返回
From javadocs
submit(Callable<T> task)
提交执行返回值任务并返回表示未完成任务结果的Future 。
Future<?> submit(Runnable task)
提交一个Runnable任务用于执行,并返回一个Future表示 任务。
void execute(Runnable command)
在未来某个时间执行给定的命令。执行程序可以根据执行程序的执行情况,在新线程,池线程或调用线程中执行该命令。
您必须在使用submit()
时采取预防措施。它在框架本身中隐藏了异常,除非将任务代码嵌入到try{} catch{}
块中。
示例代码:此代码吞咽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();
}
}
输出:
java ExecuteSubmitDemo
creating service
a and b=4:0
相同代码抛出通过与execute
()替换submit()
:
替换
service.submit(new Runnable(){
与
service.execute(new Runnable(){
输出:
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)
同时使用提交如何处理这些类型的场景()?
- 嵌入你的任务代码(无论Runnable或赎回实现)使用try {}赶上{}块代码
- 实施
CustomThreadPoolExecutor
新的解决方案:
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);
}
}
输出:
java ExecuteSubmitDemo
creating service
a and b=4:0
java.lang.ArithmeticException:/by zero
请注意,这种行为并不能保证,因为它取决于你的'Runnable'是否被包装在'Task'中或者你没有控制权。例如,如果你的'Executor'实际上是一个'ScheduledExecutorService',你的任务将被内部包装在一个'Future'中,并且未被捕获'Throwable's将被绑定到这个对象上。 – rxg 2013-06-13 08:55:07
我的意思是'包裹在未来'或不'',当然。例如,查看Javadoc的[ScheduledThreadPoolExecutor#execute](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html#execute(java.lang.Runnable)),例如。 – rxg 2013-06-13 09:28:43