如何确定核心线程数
线程池如何知道一个线程的任务已经执行完成
如果想在线程池外部去获得线程池内部任务的执行状态,由于线程本身没有返回值,所以只能通过阻塞-唤醒的方式来实现
- 线程池提供了一个 isTerminated() 方法,可以判断线程池的运行状态,我们可以循环判断isTerminated0方法的返回结果来了解线程池的运行状态,但是!想要通过这个方法获取状态的前提是,程序中主动调用了线程池的 shutdown() 方法。在实际业务中,一般不会主动去关闭线程池,因此这个方法在实用性和灵活性方面都不是很好
- 在线程池中,有一个 submit() 方法,它提供了一个 Future 的返回值,我们通过Future.get() 方法来获得任务的执行结果,当线程池中的任务没执行完之前,future.get()方法会一直阻塞,直到任务执行结束。因此,只要 future.get()方法正常返回,也就意味着传入到线程池中的任务已经执行完成了
- 可以引入一个 CountDownLatch 计数器,它可以通过初始化指定一个计数器进行倒计时,其中有两个方法分别是 await() 阻塞线程,以及 countDown() 进行倒计时,一旦倒计时归零,所以被阻塞在 await()方法的线程都会被释放
线程池的线程回收
首先,线程池里面分为
核心线程
和
非核心线程
当线程池里面的队列满了的情况下,为了增加线程池的任务处理能力。线程池会增加非核心线程
(
救急线程)
。核心线程和非核心线程的数量,是在构造线程池的时候设置的,也可以动态进行更改。由于非核心线程是为了解决任务过多的时候临时增加的,所以当任务处理完成后,工作线程处于空闲状态的时候,就需要回收。
非核心线程的回收是通过
阻塞队列里面的
poll
方法
来完成的。这个方法提供了
超时时间
和
超时时间
单位
这两个参数,当超过指定时间没有获取到任务的时候,
poll
方法返回
null
,从而终止当前线程完成线程回收。
默认情况下,线程池只会回收非核心线程,如果希望核心线程也要回收,可以设置allowCoreThreadTimeOut 这个属性为
true
,一般情况下我们不会去回收核心线程。因为线程池本身就是实现线程的复用,而且这些核心线程在没有任务要处理的时候是处于阻塞状态并没有占用CPU
资源。