在使用线程池的时候,看到execute()与submit()方法。都可以使用线程池执行一个任务,但是两者有什么区别呢?
execute
void execute(Runnable command);
submit
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
相同点:
1 都可以执行任务
2 参数都支持runnable
不同点:
1 submit支持接收返回值 详见例1。
2 execute 任务里面的异常必须捕获,不能向上抛出;submit支持的Callable支持向上抛出异常,需要由返回值.get()来进行接收。详见例2。
例1:
public class ExecutorTest {
public static ExecutorService executorService = Executors.newFixedThreadPool(3);
public static void main(String[] args) {
Future<?> result1 = executorService.submit(new Callable() {
@Override
public Object call() throws Exception {
TimeUnit.SECONDS.sleep(10);
System.out.println("Thread1 sleep 10 seconds");
return true;
}
});
Future<?> result2 = executorService.submit(new Callable() {
@Override
public Object call() throws Exception {
TimeUnit.SECONDS.sleep(5);
System.out.println("Thread2 sleep 5 seconds");
return false;
}
});
try {
System.out.println("Thread1 return:"+result1.get());
System.out.println("Thread2 return:"+result2.get());
System.out.println("finished");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
该例子的返回结果:
Thread2 sleep 5 seconds
Thread1 sleep 10 seconds
Thread1 return:true
Thread2 return:false
finished
解释:可以看到接收到了两个线程的返回结果。利用thread.sleep来模拟耗时操作,直到两个线程执行完毕之后,才会输出finished。利用Callable的返回阻塞,来等待这n个线程的执行完毕,然后将这n个线程的结果响应回去;其执行时间,基本上取决于最耗时的那个线程。
适用场景:在某些情况下,需要获得一组线程的结果,给调用端。
例2:
而execute不支持向上抛出异常,必须将异常捕获。