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

蓝月亮
发布于 2020-9-16 13:37
浏览
0收藏

向线程池提交任务的两个方法 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() 方法提交的任务都是会显示报与之对应的错误的。

 

 

作者:一个长不胖的程序YUAN

来源:CSDN

分类
已于2020-9-16 13:37:57修改
收藏
回复
举报
回复
    相关推荐