Java多线程(3):ThreadPool(上)
您好,我是湘王,这是我的云海天,欢迎您来,欢迎您再来~
开完一趟车完整的过程是启动、行驶和停车,但老司机都知道,真正费油的不是行驶,而是长时间的怠速、频繁地踩刹车等动作。因为在速度切换的过程中,发送机要多做一些工作,当然就要多费一些油。
而一个Java线程完整的生命周期就包括:
1、T1:创建(启动)
2、T2:运行(行驶)
3、T3:销毁(停车)
而T1 + T3的开销(汽油或者时间)是要远大于T2的。所以,即使是性能再好的车,或者性能再好的计算机,如果经常有T1 + T3的操作存在,那么显然是扛不住的。
所以,为了解决这种因为切换不同线程导致的效率问题,Java推出了线程池技术。通过对已创建线程的合理重用,既能解决上述问题,又能进一步提高响应速度,提升系统性能和稳定性。线程池特别适合下面的应用场景:
1、单个任务处理时间较短
2、需要处理的任务数量大
比如硬件数据采集,像手机、车载和安防传感器的数据采集就特别符合这种情况。
这是线程池相关继承结构图:
很多人都分不清Executor和Executors这两个东西:Executor是接口,是一个根据一组执行策略调用、调度、执行和控制的异步任务框架,提供了一种将“任务提交”与“任务如何运行”分离开的机制。而Executors则是一个工具类(不用new),提供了诸多用于线程池的静态方法。Executor和Executors的关系,和Java I/O中Collection和Collections的关系一毛一样。所以下次再看到XXX和XXXs的时候应该就知道Java的调性了。
说起来还是有点枯燥,那么我拿之前做的一个例子来说一下就明白了。
假设有一个工地有若干项目经理和工人,1个经理+1个工人组成工作小队,工地有很多个这样的工作小队,这些工作小队需要加入项目组,但是只有有活干的才能加入,没活干的加不了,就能要被优化裁员。
/** * 工人 * * @author 湘王 */ public class Worker { /** * 干活 */ public void dosomething() { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("挖坑"); } }