课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
线程池是程序员在学习java编程开发语言的时候需要重点掌握的编程技术,下面我们就通过案例分析来了解一下,线程池回收工作线程执行步骤。
未调用shutdown,RUNNING状态下全部任务执行完成的场景。
这种场景,会将工作线程的数量减少到核心线程数大小(如果本来就没有超过,则不需要回收)。
案例场景分析
比如一个线程池,核心线程数为4,大线程数为8。
开始是4个工作线程,当任务把任务队列塞满,就得将工作线程增加到8。
当后面任务执行到差不多了,线程取不到任务了,就会回收到4个工作线程的状态(取决于allowCoreThreadTimeOut的值,这里讨论默认值false的情况,即核心线程不会超时。如果为true,工作线程可以全部销毁)。
可以先排除上面提到的条件1,线程池的状态已经是STOP,TIDYING,TERMINATED,或者是SHUTDOWN且工作队列为空。
因为线程池一直是RUNNING,这条判断永远是false。在这个场景中,可以当条件1不存在。
下面分析取不出任务时线程是怎么运行的。
从任务队列取任务有两种方式,超时等待还是可以一直阻塞下去。决定因素是timed变量。该变量在前面赋值,如果当前线程数大于核心线程数,变量timed为true,否则为false(当然是在:allowCoreThreadTimeOut为false的情况)。
现在讨论的是timed为true的情况。keepAliveTime一般不设置,默认值为0,所以基本上可以认为是不阻塞,马上返回取任务的结果,在线程超时等待唤醒之后,发现取不出任务,timeOut变为true,进入下一次循环。
来到1的判断,线程池一直RUNNING,不进入代码块。
来到2的判断,这时任务队列为空,条件成立,CAS减少线程数,若成功,返回,否则,重复1。
注意,有可能多条线程同时通过2的判断,那会不会减少后线程的数量反而比预想的核心线程数少呢?
比如当前线程数已经只有5条了,此时有两条线程同时唤醒,通过2的判断,同时减少数量,那剩下的线程数反而只有3条,和预期不一致。
实际上是不会的,为了防止这种情况,compareAndDecrementWorkerCount(c)用的是CAS方法,如果CAS失败就continue,进入下一轮循环,重新判断。
像上述例子,其中一条线程会CAS失败,然后重新进入循环,发现工作线程数已经只有4了,timed为false,这条线程就不会被销毁,可以一直阻塞了(workQueue.take)。
从这里也可以看出,虽然有核心线程数,但线程并没有区分是核心还是非核心,并不是先创建的就是核心,超过核心线程数后创建的就是非核心,终保留哪些线程,完全随机。
shutdown
调用shutdown,全部任务执行完成的场景
这种场景,无论是核心线程还是非核心线程,所有工作线程都会被销毁。
在调用shutdown之后,会向所有的空闲工作线程发送中断信号。
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。