回复
演示提交任务方法execute()、submit()的区别
蓝月亮
发布于 2020-9-16 13:37
浏览
0收藏
向线程池提交任务的两个方法 execute()、submit() 的区别,我总结的主要有四点
(1)申明位置不同:execute() 方法定义在 Executor 接口中,submit() 方法定义在 ExecutorService 接口中;ExecutorService 接口继承了 Executor 接口。
(2)可传参数不同: execute() 方法参数只能传入 Runnable 接口;submit() 方法有三个重载的方法;
public interface ExecutorService extends Executor {
//其他代码
Future<?> submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);
<T> Future<T> submit(Callable<T> task);
//其他代码
}
(3) 有无返回值不同:execute() 方法没有返回值是 void;submit() 方法用于提交需要返回值的任务。线程池会返回一个 future 类型的对象,通过这个 future对象可以判断任务是否执行成功,并且可以通过future的 get() 方法来获取返回值,get() 方法会阻塞当前线程直到任务完成,而使用 get(long timeout,TimeUnit unit)方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务都还没有执行完就返回的,时间一到就会返回当前的结果。
(4) 如果我们希望调用者能够知道内部有 Exception 并做处理,那么就需要实现 Callable 接口,并且通过对Future.get() 进行抛出异常的捕获,然后对其进行处理。
演示第(4)点的代码:
package com.dai.test;
import java.util.concurrent.*;
public class ThreadPoolTest implements Callable {
@Override
public Integer call() {
System.out.println("开始执行call...");
System.out.println(1 / 0);
System.out.println("报错就不会执行这了");
return 1;
}
public static void main(String[] args) {
ExecutorService pool = new ThreadPoolExecutor(//1、核心线程 2、最大线程
3, 3, 0, TimeUnit.SECONDS,//3、空闲等待时间 4、等待时间单位
new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),//5、等待队列 6、线程工厂
new ThreadPoolExecutor.AbortPolicy());//7、拒绝策略
FutureTask<Integer> task = new FutureTask<>(new ThreadPoolTest());
pool.submit(task);//execute()提交也会打印错误信息
try {
Integer integer = task.get(); //假如不调用get() 就不会有任务错误信息
System.out.println(integer);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
pool.shutdown();//停止接受任务,已提交的任务还是会继续执行完
}
}
执行打印结果:
开始执行call...
java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.dai.test.ThreadPoolTest.main(ThreadPoolTest.java:23)
Caused by: java.lang.ArithmeticException: / by zero
at com.dai.test.ThreadPoolTest.call(ThreadPoolTest.java:10)
at com.dai.test.ThreadPoolTest.call(ThreadPoolTest.java:5)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Process finished with exit code 0
其实只要你代码中有对返回值明确的处理异常, execute() 、submit() 方法提交的任务都是会显示报与之对应的错误的。
作者:一个长不胖的程序YUAN
来源:CSDN
分类
已于2020-9-16 13:37:57修改
赞
收藏
回复
相关推荐