线程池的异常处理

【并发编程】知识脉络 中学习和使用了ThreadPoolExecutor线程池

但是线程池中的线程执行任务时候出现异常怎么办?该如何处理?

目录

模拟任务中出现异常

第一种情况:对异常不做任何处理

任务类:

 测试类

测试结果:

第二种情况:throw抛出异常

任务类:

测试类

 测试结果

第三种情况:捕获异常

任务类

 测试类

测试结果

总结

为避免线程池停止工作,为避免异常被吞,请手动捕获处理异常!


模拟任务中出现异常

第一种情况:对异常不做任何处理

任务类:

/**
 * @Description : TODO 模拟任务执行过程中出现异常,且不做任何处理
 * @Author : lixiunan
 * @Date : 2021/7/20
 **/
@Slf4j
public class NoneTask implements Runnable{
    @Override
    public void run() {
        log.info("开始");
        //时间戳摩2会有机会==1进入
        if(System.currentTimeMillis() % 2 == 1){
            //制造异常阻断程序正常执行
            int i = 5/0;
            log.info("异常了");
        }else{
            log.info("正常");
        }
        log.info("结束");
    }
}

 测试类

/**
 * @Description : TODO 开启两个线程,每间隔5秒就重复执行一次任务
 * @Author : lixiunan
 * @Date : 2021/7/20
 **/
public class TestScheduleException {

    public static void main(String[] args) {
        final int CORE_SIZE = 2;
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor =
                new ScheduledThreadPoolExecutor(CORE_SIZE);
        for (int i = 0; i < CORE_SIZE; i++) {
            scheduledThreadPoolExecutor.scheduleWithFixedDelay(
                    new NoneTask(),1000,5000, TimeUnit.MILLISECONDS);
        }
    }

}

测试结果:

[pool-1-thread-1] INFO testException.NoneTask - 开始
[pool-1-thread-1] INFO testException.NoneTask - 正常
[pool-1-thread-1] INFO testException.NoneTask - 结束
[pool-1-thread-2] INFO testException.NoneTask - 开始
[pool-1-thread-2] INFO testException.NoneTask - 正常
[pool-1-thread-2] INFO testException.NoneTask - 结束
[pool-1-thread-1] INFO testException.NoneTask - 开始
[pool-1-thread-2] INFO testException.NoneTask - 开始

程序会卡住!并不结束!并不输出任何的信息! 

第二种情况:throw抛出异常

任务类:

/**
 * @Description : TODO 假设>5秒就是异常情况,并抛出异常
 * @Author : lixiunan
 * @Date : 2021/7/20
 **/
@Slf4j
public class ThrowTask implements Runnable{
    @SneakyThrows
    @Override
    public void run() {
        log.info("开始");
        int time = random();
        if(time >= 5){//任务执行有异常 : 并显式地去抛出异常
            throw new RuntimeException("任务执行超过五秒有异常");
        }else {//任务执行正常
            log.info("正常执行任务");
            Thread.sleep(time*1000);
        }
        log.info("结束");
    }

    /**
     * 随机生成1-10之间的数
     * @return
     */
    public int random(){
        Random rand = new Random();
        return rand.nextInt(10)+1;
    }
}

测试类

/**
 * @Description : TODO 开启两个线程,每间隔5秒就重复执行一次任务
 * @Author : lixiunan
 * @Date : 2021/7/20
 **/
public class TestScheduleException {

    public static void main(String[] args) {
        final int CORE_SIZE = 2;
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor =
                new ScheduledThreadPoolExecutor(CORE_SIZE);
        for (int i = 0; i < CORE_SIZE; i++) {
            scheduledThreadPoolExecutor.scheduleWithFixedDelay(
                    new ThrowTask(),1000,5000, TimeUnit.MILLISECONDS);
        }
    }

}

 测试结果

[pool-1-thread-2] INFO testException.ThrowTask - 开始
[pool-1-thread-1] INFO testException.ThrowTask - 开始
[pool-1-thread-1] INFO testException.ThrowTask - 正常执行任务
[pool-1-thread-1] INFO testException.ThrowTask - 结束
[pool-1-thread-1] INFO testException.ThrowTask - 开始

程序会卡住!并不结束!并不输出任何的信息! 

第三种情况:捕获异常

任务类

/**
 * @Description : TODO 对执行的逻辑进行try包裹
 * @Author : lixiunan
 * @Date : 2021/7/20
 **/
@Slf4j
public class CatchTask implements Runnable{
    @SneakyThrows
    @Override
    public void run() {
        log.info("开始");
        try {
            if(System.currentTimeMillis() % 2 == 1){
                Thread.sleep(5000);
                throw new RuntimeException("模拟异常");
            }else{
                log.info("正常执行");
                Thread.sleep(1000);
            }

        }catch (RuntimeException e){
            log.info("捕获到模拟异常");
        }
        log.info("结束");
    }
}

 测试类

/**
 * @Description : TODO 开启两个线程,每间隔5秒就重复执行一次任务
 * @Author : lixiunan
 * @Date : 2021/7/20
 **/
public class TestScheduleException {

    public static void main(String[] args) {
        final int CORE_SIZE = 2;
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor =
                new ScheduledThreadPoolExecutor(CORE_SIZE);
        for (int i = 0; i < CORE_SIZE; i++) {
            scheduledThreadPoolExecutor.scheduleWithFixedDelay(
                    new CatchTask(),1000,5000, TimeUnit.MILLISECONDS);
        }
    }

}

测试结果

[pool-1-thread-1] INFO testException.CatchTask - 开始
[pool-1-thread-1] INFO testException.CatchTask - 正常执行
[pool-1-thread-2] INFO testException.CatchTask - 开始
[pool-1-thread-2] INFO testException.CatchTask - 正常执行
[pool-1-thread-1] INFO testException.CatchTask - 结束
[pool-1-thread-2] INFO testException.CatchTask - 结束
[pool-1-thread-1] INFO testException.CatchTask - 开始
[pool-1-thread-2] INFO testException.CatchTask - 开始
[pool-1-thread-1] INFO testException.CatchTask - 捕获到模拟异常
[pool-1-thread-1] INFO testException.CatchTask - 结束
[pool-1-thread-2] INFO testException.CatchTask - 捕获到模拟异常
[pool-1-thread-2] INFO testException.CatchTask - 结束
[pool-1-thread-1] INFO testException.CatchTask - 开始
[pool-1-thread-2] INFO testException.CatchTask - 开始
[pool-1-thread-2] INFO testException.CatchTask - 捕获到模拟异常
[pool-1-thread-2] INFO testException.CatchTask - 结束
[pool-1-thread-1] INFO testException.CatchTask - 捕获到模拟异常
[pool-1-thread-1] INFO testException.CatchTask - 结束
[pool-1-thread-2] INFO testException.CatchTask - 开始
[pool-1-thread-2] INFO testException.CatchTask - 正常执行
[pool-1-thread-1] INFO testException.CatchTask - 开始
[pool-1-thread-1] INFO testException.CatchTask - 正常执行
[pool-1-thread-1] INFO testException.CatchTask - 结束
[pool-1-thread-2] INFO testException.CatchTask - 结束

程序会一直正常执行!并输出有异常时的信息!  

总结

为避免线程池停止工作,为避免异常被吞,请手动捕获处理异常!

你可能感兴趣的:(并发编程专题,java,并发编程,线程池)