这篇文章将为大家详细讲解有关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中线程池的内部原理分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。