千家信息网

Java中线程池的内部原理分析

发表于:2024-11-20 作者:千家信息网编辑
千家信息网最后更新 2024年11月20日,这篇文章将为大家详细讲解有关Java中线程池的内部原理分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。先看一下ThreadPoolExecutor类的execut
千家信息网最后更新 2024年11月20日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中线程池的内部原理分析"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

0