图解为什么要使用线程池?
根据线程的实际情况,我们发现, 同样的时间里,下面的的效率远远大于上面的,所以我们要构建一种可以运行很多个逻辑片段,只进行一次创建和销毁的模型,
所以我们提出了线程池模型。
一个线程池的属性起码包含初始化线程数量、线程数组、任务队列。
- 初始化线程数量指线程池初始化的线程数,
- 线程数组保存了线程池中的所有线程
- 任务队列指添加到线程池中等待处理的所有任务。
线程池里有两个线程,池里线程的工作就是不断循环检测任务队列中是否有需要执行的任务,如果有,则处理并移出任务队列。于是,可以说线程池中的所有线程的任务就是不断检测任务队列并不断执行队列中的任务。
JUC就是java.util .concurrent工具包的简称。这是一个处理线程的工具包,JDK 1.5开始出现的。
- 创建线程的方式 — 实现Callable接口
- 闭锁
- 锁分段机制
- volatile关键字与内存可见性
使用线程池时只须实例化一个对象,构造函数就会创建相应数量的线程并启动线程,启动的线程无限循环地检测任务队列,执行方法execute()仅仅把任务添加到任务队列中。
所有任务都必须实现Runnable接口,这是线程池的任务队列与工作线程的约定
JUC工具包作者Doug Lea当时如此规定,工作线程检测任务队列并调用队列的run()方法,假如你自己重新写一个线程池,就完全可以自己定义一个不一样的任务接口。
一个完善的线程池并不像下面的例子那样简单,它需要提供启动、销毁、增加工作线程的策略,最大工作线程数,各种状态的获取等操作,而且工作线程也不可能始终做无用循环,需要对任务队列使用wait, notify优化,或者将任务队列改用为阻塞队列(生产者消费者模式)。