线程池的异常处理

【并发编程】知识脉络 中学习和使用了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 - 结束

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

总结

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在C++中,线程池异常处理主要是通过捕获和处理线程中抛出的异常来实现的。以下是一个简单的示例,展示了如何在C++线程池中使用异常处理: ```cpp #include <iostream> #include <thread> #include <vector> #include <functional> #include <stdexcept> #include <future> #include <mutex> #include <condition_variable> #include <queue> class ThreadPool { public: ThreadPool(size_t); template<class F, class... Args> auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type>; ~ThreadPool(); private: // need to keep track of threads so we can join them std::vector< std::thread > workers; // the task queue std::queue< std::function<void()> > tasks; // synchronization std::mutex queue_mutex; std::condition_variable condition; bool stop; }; // the constructor just launches some amount of workers inline ThreadPool::ThreadPool(size_t threads) : stop(false) { for(size_t i = 0;i<threads;++i) workers.emplace_back( [this] { for(;;) { std::function<void()> task; { std::unique_lock<std::mutex> lock(this->queue_mutex); this->condition.wait(lock, [this]{ return this->stop || !this->tasks.empty(); }); if(this->stop && this->tasks.empty()) return; task = std::move(this->tasks.front()); this->tasks.pop(); } try { task(); } catch(const std::exception& e) { // handle exception in task std::cerr << "Exception in thread: " << e.what() << "\n"; } catch(...) { // unknown exception in task std::cerr << "Unknown exception in thread\n"; } } } ); } // add new work item to the pool template<class F, class... Args> auto ThreadPool::enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> { using return_type = typename std::result_of<F(Args...)>::type; auto task = std::make_shared< std::packaged_task<return_type()> >( std::bind(std::forward<F>(f), std::forward<Args>(args)...) ); std::future<return_type> res = task->get_future(); { std::unique_lock<std::mutex> lock(queue_mutex); // don't allow enqueueing after stopping the pool if(stop) throw std::runtime_error("enqueue on stopped ThreadPool"); tasks.emplace([task](){ (*task)(); }); } condition.notify_one(); return res; } // the destructor joins all threads inline ThreadPool::~ThreadPool() { { std::unique_lock<std::mutex> lock(queue_mutex); stop = true; } condition.notify_all(); for(std::thread &worker: workers) worker.join(); } ``` 在这个示例中,我们创建了一个`ThreadPool`类,它有一个任务队列和一个工作线程列表。当我们向线程池提交一个任务时,这个任务会被添加到任务队列中。工作线程会从队列中取出任务并执行。如果任务中的代码抛出了异常,我们可以在任务中捕获并处理这个异常

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java程序员调优

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值