hi,你好!欢迎访问本站!登录
本站由网站地图腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 教程 - 杂谈 - 正文 君子好学,自强不息!

通俗易懂地给女朋友讲:线程池的内部道理

2019-11-18杂谈搜奇网26°c
A+ A-

餐厅的约会

餐盘在灯光的晖映下分外晶莹皎洁皎洁,女朋友拿起红羽觞轻轻地抿了一小口,对我说:“常常听你说线程池,究竟线程池究竟是个什么道理?”我楞了一下,内心想女朋友本日是怎样了,怎样倏忽问出这么专业的题目,但做为一个专业人士在女朋友眼前也不能露怯啊,想了一下便说:“我先给你讲讲我前同事老王的故事吧!”迎接关注微信民众号:万猫学社,每周一分享Java手艺干货。

大龄程序员老王

老王是一个已北漂十多年的程序员,年龄大了,加班加不动了,升迁也无望,因而拿着手里的一些蓄积,回老家转行创业。他挑选了沐浴行业,开一家沐浴中间,是的,一家正规的沐浴中间。之前在北京的时刻,喜好去的澡堂叫“清华池”,他想了想,就给本身的沐浴中间取名为“线程池”。迎接关注微信民众号:万猫学社,每周一分享Java手艺干货。

线程池沐浴中间

线程池开业今后,老王发明有主顾想做足疗,因而就雇用了1个足疗技师,多增添了一项营业增添了收入。跟着做足疗的主顾增添,为了赚更多钱又雇用了4个足疗技师。
过了一段时候,沐浴中间的买卖越来越好,做足疗的主顾也越来越多。然则,老王发明本身店里的足疗技师已有5个足疗技师,再雇用就太多了,付出不起再多工资了。足疗技师忙不过来怎样办?老王是个聪明人,立时想到要领:让主顾列队,有哪一个足疗技师做完了,余暇出来了,就在部队里再叫一个主顾继承做。迎接关注微信民众号:万猫学社,每周一分享Java手艺干货。

劳碌的周末

一到周末,来沐浴中间的主顾比日常平凡多了几倍,想足疗的主顾列队时候太长,主顾们已不耐烦了。老王立时做出回响反映,又紧要从其他沐浴中间雇用了5个足疗技师,为部队里主顾做足疗,大大削减列队的主顾。
不过,偶然买卖太火爆了,紧要雇用的技师也用上了,主顾列队时候也是很长,再来新的主顾,老王只能满脸赔笑地和主顾说:“您下次再来吧,下次给您找个好技师。”,把主顾拒之门外。
过了周末今后,店里不能养闲人啊,老王就把紧要雇用的技师都辞退了。迎接关注微信民众号:万猫学社,每周一分享Java手艺干货。

老王的经营之道

老王的买卖越做越红火,很快就要开分店、融资上市、走上人生顶峰。既然这么胜利,就让我们来复盘一下他的经营之道吧。

假如你了解了老王的经营之道,线程池就不难理解了,把主顾替换成使命,把足疗技师替换成线程线程池沐浴中间就是线程池了,线程池的内部道理就是如许的:

迎接关注微信民众号:万猫学社,每周一分享Java手艺干货。

梦醒

铃铃铃,闹铃把我吵醒,原来是一场梦啊,我哪有什么女朋友?本日上午有一个口试,赶忙起床洗漱终了,就出发了。在路上追念谁人新鲜的梦,要不再温习一下线程池的内部道理吧!
先看一下ThreadPoolExecutor类的execute要领:

public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
    //猎取clt,clt纪录着线程池状况和运转线程数。
    int c = ctl.get();
    //运转线程数小于中心线程数时,建立线程放入线程池中,而且运转当前使命。
    if (workerCountOf(c) < corePoolSize) {
        if (addWorker(command, true))
            return;
        //建立线程失利,从新猎取clt。
        c = ctl.get();
    }
    //线程池是运转状况而且运转线程大于中心线程数时,把使命放入行列中。
    if (isRunning(c) && workQueue.offer(command)) {
        int recheck = ctl.get();
        //从新搜检线程池不是运转状况时,
        //把使命移除行列,并经由过程谢绝战略对该使命举行处置惩罚。
        if (! isRunning(recheck) && remove(command))
            reject(command);
        //当前运转线程数为0时,建立线程到场线程池中。
        else if (workerCountOf(recheck) == 0)
            addWorker(null, false);
    }
    //运转线程大于中心线程数时而且行列已满时,
    //建立线程放入线程池中,而且运转当前使命。
    else if (!addWorker(command, false))
        //运转线程大于最大线程数时,失利则谢绝该使命
        reject(command);
}

在execute要领中,屡次挪用的addWorker要领,再看一下这个要领:

private boolean addWorker(Runnable firstTask, boolean core) {
    retry:
    for (;;) {
        //猎取clt,clt纪录着线程池状况和运转线程数。
        int c = ctl.get();
        //猎取线程池的运转状况。
        int rs = runStateOf(c);

        //线程池处于封闭状况,或许当前使命为null
        //或许行列不为空,则直接返回失利。
        if (rs >= SHUTDOWN &&
            ! (rs == SHUTDOWN &&
               firstTask == null &&
               ! workQueue.isEmpty()))
            return false;

        for (;;) {
            //猎取线程池中的线程数
            int wc = workerCountOf(c);
            //线程数凌驾CAPACITY,则返回false;
            //这里的core是addWorker要领的第二个参数,
            //假如为true则依据中心线程数举行比较,
            //假如为false则依据最大线程数举行比较。
            if (wc >= CAPACITY ||
                wc >= (core ? corePoolSize : maximumPoolSize))
                return false;
            //尝试增添线程数,假如胜利,则跳出第一个for轮回
            if (compareAndIncrementWorkerCount(c))
                break retry;
            //假如增添线程数失利,则从新猎取ctl
            c = ctl.get();
            //假如当前的运转状况不等于rs,申明状况已被转变,
            //返回第一个for轮回继承实行
            if (runStateOf(c) != rs)
                continue retry;
        }
    }

    boolean workerStarted = false;
    boolean workerAdded = false;
    Worker w = null;
    try {
        //依据当前使命来建立Worker对象
        w = new Worker(firstTask);
        final Thread t = w.thread;
        if (t != null) {
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                //取得锁今后,从新搜检线程池状况
                int rs = runStateOf(ctl.get());

                if (rs < SHUTDOWN ||
                    (rs == SHUTDOWN && firstTask == null)) {
                    if (t.isAlive())
                        throw new IllegalThreadStateException();
                    //把方才建立的线程到场到线程池中
                    workers.add(w);
                    int s = workers.size();
                    //纪录线程池中涌现过的最大线程数目
                    if (s > largestPoolSize)
                        largestPoolSize = s;
                    workerAdded = true;
                }
            } finally {
                mainLock.unlock();
            }
            if (workerAdded) {
                //启动线程,最先运转使命
                t.start();
                workerStarted = true;
            }
        }
    } finally {
        if (! workerStarted)
            addWorkerFailed(w);
    }
    return workerStarted;
}

迎接关注微信民众号:万猫学社,每周一分享Java手艺干货。

口试

一个中年男子坐在我眼前,对我说:“您好,我是本日的口试官。”我微笑地回应:“您好。”口试官面无表情地问我:“线程池肯定用过吧,能说说线程池的内部道理嘛?”我差点笑作声来,自信满满地说……迎接关注微信民众号:万猫学社,每周一分享Java手艺干货。

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  移步手机端
通俗易懂地给女朋友讲:线程池的内部道理

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
未定义标签

本文来源:搜奇网

本文地址:https://www.sou7.cn/282231.html

关注我们:微信搜索“搜奇网”添加我为好友

版权声明: 本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。请记住本站网址https://www.sou7.cn/搜奇网。

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>