一、线程池解决的问题:
缓存线程,节约创建线程和销毁线程的时间
二、线程池的体系
public interface Executor
public interface ExecutorService extends Executor
public abstract class AbstractExecutorService implements ExecutorService
public class ThreadPoolExecutor extends AbstractExecutorService
其中 Execotor中的 void execute(Runnable command) 是整个线程池执行的核心执行方法
在ThreadPoolExecutor中有对 exector 方法的实现过程
主要实现原理为:
当一个新任务过来时线程池会创建一个新的线程去处理任务,当任务处理完过后还没有新的任务过来时,这个线程会回到线程池中保持一段存活时间,当有许多任务来的时候线程池会根据核心线程数的限制创建出不超过核心线程数的线程数量去处理任务,当创建出来的线程数量小于任务数时,即有些任务没有对应的线程处理,这些任务会被放在阻塞队列中,当阻塞队列满啦,线程池会尝试着创建新的线程去处理任务,如果新创建的线程池数量加上之前创建的核心线程数量大于线程池最大数量时,并且阻塞队列也满啦,这个时候会反馈一些拒绝策略 1.整个任务停止 2.提供反馈(太快啦,慢一点) 3.没有反馈把后来的任务直接扔掉 4.扔掉老的任务类似于LRU算法那样。
三、创建一个线程池
创建线程池可以用Executors的工厂方法newFixedThreadPool、newSingleThreadExecutor、newCachedThreadPool等方法来创建。还可以通过 ThreadPoolExecutor的构造方法自己创建一个线程池(自己创建时要配置好参数)
使用submit方法来使用线程池返回一个Future,submit调用的就是exector。个人理解Future这个类是对任务的监控管理,用来管理每个任务的状态,然后把任务交给其他线程进行执行。所有的线程都在 HasSet 类型的workers中,这个也是真正的线程池,里面用来存放线程。works中通过runworker让线程运行任务完成线程的复用和移除,通过addWorker创建线程向workers中添加。runworker中用gettask来从阻塞对列中取任务。FutureTask通过适配器模式实现接口RunnableFuture 这个接口就是一个适配器通过继承 Runnable和Future让FutureTask具有 Runnable和Future的功能。
- 参考文章
(https://www.jianshu.com/p/edab547f2710)
(https://blog.csdn.net/fxkcsdn/article/details/82316046)