线程池提交任务(submit 和 execute)

导读:本篇文章讲解 线程池提交任务(submit 和 execute),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

提交任务有execute()submit()两个方法,下面看看他俩的区别:

接收参数不同

execute()的参数只有Runnable;

ynbCjS.png

submit()既可以提交Runnable类型的任务,也可以提交Callable类型的任务。
ynqP8x.png
ynqErD.png

返回值不同

execute() 没有返回值;

submit() 有返回值Future通过Future可以获取各个线程的完成情况,是否有异常,还能试图取消任务的执行

异常处理不同

execute()在执行任务时,如果遇到异常会直接抛出;

submit()不会直接抛出,只有在使用Future#get方法获取返回值时,才会抛出异常

假设我有很多更新各种数据的task,我希望如果其中一个task失败,其它的task就不需要执行了。那我就需要catch Future#get抛出的异常,然后终止其它task的执行。

下面看个使用submit()获取返回值的例子:

public static void main(String[] args) {

    // 创建固定大小的线程池
    // return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
    ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
    System.out.println("threadPool start...");

    // 提交任务 submit(Callable<T> task), 获取 任务的future
    Future<Integer> future = threadPool.submit(new Callable<Integer>() {
        @Override
        public Integer call() throws Exception {
            try {
                // 主动触发算术异常
                // int a = 10 / 0;
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 111;
        }
    });

    // 通过 future#isDone 可以 查看 task 线程是否完成;
    // 其实,只要 task 的 call 方法结束,
    // 1 无论是 正常结束, 还时 异常结束,都代表任务已经结束,统一返回true

    // 通过 future#get 可以 得到 task线程的返回值;
    // get 方法是同步阻塞方法,会阻塞到任务结束为止,
    // 1 一般和future#isDone 配合使用,轮询任务的状态
    // 2 如果 任务线程中途 (被取消,发生异常,被中断),get 方法都会抛出异常

    Integer value = -1;
    try {
        // 轮询判断任务是否完成
        for (; ; ) {
            // 如果 任务完成
            if (future.isDone()) {
                // 阻塞到任务完成为止
                // 这里 不会诸塞,因为任务明显完成了
                value = future.get();
                System.out.println("任务顺利完成,future#isDone=" + future.isDone() + ", 返回值=" + value);
                break;
            } else {
                // 任务未完成
                System.out.println("任务未完成, future#isDone=" + future.isDone());
                Thread.sleep(1000);
            }
        }
    } catch (InterruptedException | ExecutionException e) {
        // 任务发生异常,future#isDone 返回 true
        System.out.println("任务执行期间发生异常, future#isDone=" + future.isDone() +", 返回值=" + value);
        e.printStackTrace();
    }

    // 等待其他任务完成,最后才关闭线程池
    threadPool.shutdown();
    System.out.println("end。。。");
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/69740.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!