当前位置: 代码网 > it编程>编程语言>Java > java线程池核心线程不被摧毁的原理及分析

java线程池核心线程不被摧毁的原理及分析

2025年05月07日 Java 我要评论
为什么要用线程池?减少了创建和销毁线程的次数,每个工作线程都可以被重复利用可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因线程过多消耗内存,也避免了因线程过少,浪费系统资源如何做到每个工作

为什么要用线程池?

  • 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用
  • 可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因线程过多消耗内存,也避免了因线程过少,浪费系统资源

如何做到每个工作线程都可以被重复利用呢?

先看下线程池的工作原理:

原理如上图,线程池有七个核心参数

  • corepoolsize 线程池核心线程数
  • maximumpoolsize 线程池最大线程数量
  • keepalivetime 空闲线程存活时间
  • unit 空闲线程存活时间单位
  • workqueue 工作队列
  • threadfactory 线程工厂
  • handler 拒绝策略

线程池之所以能做到重复利用,是因为线程池的核心线程不会被摧毁,执行完任务后会重复利用

线程池是如何保持核心线程不被摧毁呢?

首先看先线程池是如何处理任务的,如下图

下面我们看下核心部分源码:

  • 当有一个任务添加进来时,线程池会创建一个worker,worker是实现runnable方法的,所以worker执行时会调用run方法,run方法会接着调用runwoker方法
  • 主要看这一行代码,调用gettask方法获取任务并且执行 while (task != null || (task = gettask()) != null)
final void runworker(worker w) {
        thread wt = thread.currentthread();
        runnable task = w.firsttask;
        w.firsttask = null;
        w.unlock(); // allow interrupts
        boolean completedabruptly = true;
        try {
            // 主要看这一行代码,调用gettask方法获取任务并且执行
            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 {
                    beforeexecute(wt, task);
                    throwable thrown = null;
                    try {
                        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++;
                    w.unlock();
                }
            }
            completedabruptly = false;
        } finally {
            processworkerexit(w, completedabruptly);
        }
    }
  • 看下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;
            }
        }
    }
  • 主要看这几行代码

  • gettask方法通过调用任务队列的take方法,不断的获取线程

  • 如果任务队列里面数量为0,则会一直阻塞,一直等到有任务加入,从而保证了核心线程不被摧毁

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com