JUC并发编程 共享模式之工具 ThreadPoolExecutor -- 正确处理线程池异常

Posted Z && Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JUC并发编程 共享模式之工具 ThreadPoolExecutor -- 正确处理线程池异常相关的知识,希望对你有一定的参考价值。

1. 正确处理线程池异常


1.1 如果不处理异常

示例代码:

package com.tian;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j(topic = "c.TestTimer")
public class TestTimer {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
        pool.schedule(() -> {
            log.debug("task1");
            // 主动写一个异常
            int i = 1 / 0;
        }, 1, TimeUnit.SECONDS);

        pool.schedule(() -> {
            log.debug("task2");
        }, 1, TimeUnit.SECONDS);

        pool.schedule(() -> {
            log.debug("task3");
        }, 1, TimeUnit.SECONDS);
    }
}

运行结果:

程序不会抛出任何的异常信息,直接把里面的任务执行完了,我们都不知道里面有没有发生异常。这样显然是不好的,下面介绍2种捕获异常的方式


1.2 try / catch 捕获异常

示例代码:

package com.tian;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j(topic = "c.TestTimer")
public class TestTimer {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
        pool.schedule(() -> {
        // 主动捕获异常
            try {
                log.debug("task1");
                // 主动写一个异常
                int i = 1 / 0;
            } catch (Exception e) {
                log.debug("error: {}", e);
            }
        }, 1, TimeUnit.SECONDS);

        pool.schedule(() -> {
            log.debug("task2");
        }, 1, TimeUnit.SECONDS);

        pool.schedule(() -> {
            log.debug("task3");
        }, 1, TimeUnit.SECONDS);
    }
}

运行结果:


1.3 使用 Future

示例代码:

package com.tian;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

@Slf4j(topic = "c.TestTimer")
public class TestTimer {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        ExecutorService pool = Executors.newFixedThreadPool(1);
        Future<Boolean> f = pool.submit(() -> {
            log.debug("task1");
            // 主动抛出异常
            int i = 1 / 0;
            return true;
        });
        // 如果任务里面发生了异常 则 get方法会返回异常信息
        log.debug("result:{}", f.get());
    }
}

运行结果:



以上是关于JUC并发编程 共享模式之工具 ThreadPoolExecutor -- 正确处理线程池异常的主要内容,如果未能解决你的问题,请参考以下文章

JUC并发编程 共享模式之工具 JUC Semaphore(信号量) -- 介绍 & 使用

JUC并发编程 共享模式之工具 ThreadPoolExecutor -- 正确处理线程池异常

JUC并发编程 共享模式之工具 JUC ConcurrentHashMap -- ConcurrentHashMap的错误使用和正确使用(示例:统计单词个数)

JUC并发编程 共享模式之工具 JUC Semaphore(信号量) -- Semaphore原理

JUC并发编程 共享模式之工具 JUC 线程安全的集合类 -- 线程安全的集合类概述

JUC并发编程 共享模式之工具 ThreadPoolExecutor -- 线程池应用之定时任务(在每周周四执行定时任务)