演示提交任务方法execute()、submit()的区别

时间:2020-9-9 作者:admin


向线程池提交任务的两个方法 execute()submit() 的区别,我总结的主要有四点

(1)申明位置不同:execute() 方法定义在 Executor 接口中,submit() 方法定义在 ExecutorService 接口中;
   ExecutorService 接口继承了 Executor 接口。

(2)可传参数不同: execute() 方法参数只能传入 Runnable 接口;submit() 方法有三个重载的方法;
演示提交任务方法execute()、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() 方法提交的任务都是会显示报与之对应的错误的。

有用点个关注,手留余香!😗 😗 😗

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。