Java线程池发生异常后,会发生什么

先贴一段线程池内代码

   // w 就是启动worker
    final void runWorker(Worker w) {
        // wt == w.thread。
        Thread wt = Thread.currentThread();
        // 将初始 执行 task 赋值给 task
        Runnable task = w.firstTask;
        // 清空当前 w.firstTask引用
        w.firstTask = null;
        // 为了初始化worker 的 state == 0 和 exclusiveOwnerThread == null
        w.unlock(); // allow interrupts

        // 是否是突然退出 ; false 正常退出
        boolean completedAbruptly = true;
        try {
            // 条件1: 指的是firstTask 不为 null.
            // 条件2: 说明当前线程在queue中获取任务成功. 如果返回null。
            // getTask是一个会阻塞线程的方法。说明当前线程需要执行退出逻辑
            while (task != null || (task = getTask()) != null) {

                // worker加锁设置,为当前线程
                // 为什么要设置独占锁? shutdown时会判断当前worker状态,根据独占锁是否空闲来判断当前worker是否正在工作
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted.  This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt

                // 条件1: 说明线程池目前处于 STOP/TIDYING.TERMINATION 此时线程一定要给它一个中断信号
                // 条件2: 前部分成立:说明当前线程池状态是>=STOP 且当前线程未设置中断状态;
                // 后半部分:
                // 强制刷新当前线程的中断标记 false, 有可能上一个task时,业务代码里面将当前线程的中断标记位设置为了true,且没有处理。
                // 这里一定要强制刷新一下,不会影响到后面的task
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())

                    //
                    wt.interrupt();
                try {
                    // 钩子方法,留给子类实现
                    beforeExecute(wt, task);
                    // 表现异常情况,如果thrown不为空,表示 task运行过程中,向上层抛出异常了
                    Throwable thrown = null;
                    try {
                        // task 可能是 FutureTask 也可能是Runnable接口实现类
                        task.run();
                    } catch (RuntimeException x) {
                        thrown = x; throw x;
                    } catch (Error x) {
                        thrown = x; throw x;
                    } catch (Throwable x) {
                        thrown = x; throw new Error(x);
                    } finally {
                    	// 钩子方法,留给子类实现
                        afterExecute(task, thrown);
                    }
                } finally {
                    task = null;
                    w.completedTasks++;
                    // worker处理完成一个任务后,会释放独占锁。然后再次到queue队列中获取任务
                    w.unlock();
                }
            }
            // 什么情况执行到这里?
            // 1. getTask() 返回null。 说明当前线程应该执行退出
            // 2.
            completedAbruptly = false;
        } finally {
            // task.run() 抛出异常,直接到这里
            // 正常退出 completedAbruptly 为false
            // 异常退出 completedAbruptly 为 true
            processWorkerExit(w, completedAbruptly);
        }
    }

可看到,当发生异常的时候,会跳出while()循环,在最后finally 块中有一个会调用processWorkerExit()方法。执行完这个方法后,当前线程也就自然消亡了,但是,processWorkerExit()方法中会额外再新增一个线程,这样就能维持住固定的核心线程数。

    private void processWorkerExit(Worker w, boolean completedAbruptly) {
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            completedTaskCount += w.completedTasks;
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }

        tryTerminate();

        int c = ctl.get();
        if (runStateLessThan(c, STOP)) {
            if (!completedAbruptly) {
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            addWorker(null, false);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值