线程池源码之-execute为什么执行完后main不退出

 

1、现象

main方法执行线程池后 发现线程创建完毕 但是mian 方法一直卡在那里无法退出

2、源码

2.1、执行execute后代码如下

注意看下面的addworker

class: java.util.concurrent.ThreadPoolExecutor

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

2.2、执行start会回调run方法

private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable
    {
        **
        **
        ..
        ..
        **
        /** Delegates main run loop to outer runWorker  */
        public void run() {
            runWorker(this);
        }

2.3、runworker下有个死循环

final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock(); // allow interrupts
        boolean completedAbruptly = true;
        try {
            //这块会一直进行拉取任务
            while (task != null || (task = getTask()) != null) {
                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
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    wt.interrupt();
                try {

2.4、继续查看getTask方法

private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }

            int wc = workerCountOf(c);

            // Are workers subject to culling?
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;
            }

            try {
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }

如果无超时时间,则不会结束

3,结束办法:

但是实际测试时候发现这里并不是死循环  只是一直去取  如果没任务就没了

实际测试  如果设置线程池为守护进程 就会退出(默认是非守护进程) 这个跟jvm有关

setDaemo(false);

 

参考:https://www.yuque.com/u1300481/kb/gr403g

参考:https://www.jianshu.com/p/7c7eb33a4424

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThreadPoolTaskExecutorJava 中的一个工具类,用于管理线程池执行任务。当你创建一个 ThreadPoolTaskExecutor 并使用它来提交任务后,线程池会在后台执行这些任务。线程池的设计通常是为了重用线程,提高执行效率,而不是一次性创建和销毁。 当所有任务完成后,ThreadPoolTaskExecutor 默认不会自动销毁线程池。如果你想要在所有任务执行完毕后关闭线程池,你需要调用 `shutdown()` 或 `shutdownNow()` 方法来停止接受新的任务,然后等待当前正在执行的任务完成。`shutdown()` 方法会等待已完成的任务结束,而 `shutdownNow()` 方法则会中断正在运行的任务并立即关闭线程池。 如果你希望在所有任务结束后立刻销毁线程池,你可以设置一个 Runnable 或 Callable 的实现,在其中手动调用 `Executor.shutdown()` 和 `Executor.awaitTermination()` 方法,确保线程池在所有任务结束后关闭。这里是一个简单的示例: ```java ThreadPoolExecutor executor = ... // 创建线程池 executor.execute(() -> { // 执行任务 executor.shutdown(); try { if (!executor.awaitTermination(1, TimeUnit.MINUTES)) { executor.shutdownNow(); // 如果等待超时,强制关闭线程池 } } catch (InterruptedException e) { executor.shutdownNow(); // 如果被中断,也强制关闭线程池 Thread.currentThread().interrupt(); } }); ``` 这样,当主线程退出或者达到你设置的等待时间后,线程池会被安全地销毁。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值