A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

       在开发中我们会使用到线程,而为了减少资源的损耗,提高性能,我们一般会使用线程池。线程池具有重用存在的线程,减少对象创建、消亡的开销,性能佳, 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞,提供定时执行、定期执行、单线程、并发数控制等功能。那么线程池是怎么执行的呢,我们来分析一下:

要了解线程池的执行过程,我们需要知道线程池是怎么创建的,现在我们来说其中一种:


从上面的构造方法中可以看出,线程池的创建是定义了相关的概念的,那么线程池是如何提交任务的呢,当线程池创建完毕之后,要提交任务,需要调用它里面的excute方法进行提交:
[Java] 纯文本查看 复制代码
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);
    }

可以看到,线程池处理一个任务主要分三步处理,代码注释里已经介绍了。现在我们使用图片来理解一下:

从图中我们可以看到,向线程池提交任务时,会首先判断线程池中的线程数是否大于设置的核心线程数,如果不大于,就创建一个核心线程来执行任务。
如果大于核心线程数,就会判断缓冲队列是否满了,如果没有满,则放入队列,等待线程空闲时执行任务。
如果队列已经满了,则判断是否达到了线程池设置的最大线程数,如果没有达到,就创建新线程来执行任务。
如果已经达到了最大线程数,则执行指定的拒绝策略。

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马