1 new Thread 弊端
& 每次new Thread新建对象,性能差
& 线程缺乏统一管理,可能无限制的新建线程,相互竞争,有可能占用过多系统资源导致死机或OOM
& 缺少更多功能,如更多执行,定期执行,线程中断
2 线程池的好处
1 如果线程池中的线程数量小于corePoolSize中的数量,直接创建新的线程处理任务,
2 corePoolSize < 当前线程的数量<maxImumPoolSize, 只有当workQueue满的时候才去创建新的线程去处理任务
1)
if(corePoolSize ==maxImumPoolSize)&&(workQueue未满的时候)
把请求放到workQueue里面,等待有空闲的线程从workQueue取出任务
2)
if(maxImumPoolSize满了)&&(workQueue满的时候)
通过拒绝策略去执行
workQueue
保持等待任务的阻塞队列,提交新的任务到线程池以后,会根据当前线程池中正在运行的线程数量来决定处理方式
1 直接切换 无界队列 或者有界队列
直接队列:SynchronousQueue
无界队列:基于链表的队列 LinkedBlockingQueue,能够创建的最大线程数目为corePoolSize maxImumPoolSize 不起作用了,当corePoolSize 数目的线程都在运行的时候,新的线程就会放到等待队列中去
有界队列:使用的是ArrayBlockingQueue 实现的,可以将线程的最大数目限制为maximumPoolSize,线程池对线程的调度更困难,减少了系统的资源消耗 线程池和队列的大小都是有限的
降低系统消耗:设置较大的队列容量,较小的线程池容量
提交的任务经常阻塞:可以设置最大线程数
线程池数目设置过大会导致并发量增加,需要考虑线程之间的调度
线程池设置大一点 提高CPU利用率,
2 KeepAliveTime:线程没有任务执行时最多保持多久时间终止,当线程池中线程大于corePoolSize 时候,线程保持的时间
workQueue 对应的阻塞队列满了的时候,并且没有空闲的线程池,这时候继续提交任务的时候,需要采取一种策略来处理这个任务,线程池提供了四种策略
(1,直接抛出异常
2 用调用者的线程来执行任务
3 丢弃队列中最考前的任务,并执行当前任务
4 直接丢弃这个任务 )
9.2 线程池的状态
Executor 框架:根据一组策略的调用调度一种异步的框架,将任务提交和任务运行分离的分离的机制
JUC中有三个Executor 接口: Executor ExecutorService SchedukedExecutorService
ThreadPoolExecutor 是功能最强的接口,根据需要传入参数和策略
Executor 框架接口
&&&& Executors.newCachedThreadPool 命名新的线程池 创建可缓存的线程池,如果线程池长度超过了处理的需要可以灵活的回收,如果没有就创建新的线程池
&&&& Executors.newFixedThreadPool 创建的是一种定长的线程池,可以控制线程最大的并发数,超出的线程需要等待
&&&& Executors.newScheduledThreadPool 创建的也是定长的线程池,支持定时和周期任务的执行
&&&& Executors.newSingleThreadExecutor 创建的是一个单线程化的线程池,只会用唯一的线程任务来执行,保证所有任务按照指令顺序去执行(优先级,先入先出