线程池
1.优点
1. 降低资源消耗(线程复用)
2. 提高响应速度
3. 可管理线程
2.自定义线程池
public class ThreadPoolExecutorDemo {
public static void main ( String[ ] args) {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor (
2 ,
4 ,
3 ,
TimeUnit. SECONDS,
new LinkedBlockingQueue < > ( 3 ) ,
Executors. defaultThreadFactory ( ) ,
new ThreadPoolExecutor. CallerRunsPolicy ( )
) ;
try {
for ( int i = 1 ; i <= 100 ; i++ ) {
threadPoolExecutor. execute ( ( ) - > {
System. out. println ( Thread. currentThread ( ) . getName ( ) + "==>" ) ;
} ) ;
}
} catch ( Exception e) {
e. printStackTrace ( ) ;
} finally {
threadPoolExecutor. shutdown ( ) ;
}
}
}
3.阻塞队列
ArrayBlockingQueue:基于数组结构的有界阻塞队列,按先进先出对元素进行排序。
LinkedBlockingQueue:基于链表结构的有界/ 无界阻塞队列,按先进先出对元素进行排序,吞吐量通常高于 ArrayBlockingQueue。Executors. newFixedThreadPool 使用了该队列。
SynchronousQueue:不是一个真正的队列,而是一种在线程之间移交的机制。要将一个元素放入 SynchronousQueue 中,必须有另一个线程正在等待接受这个元素。如果没有线程等待,并且线程池的当前大小小于最大值,那么线程池将创建一个线程,否则根据拒绝策略,这个任务将被拒绝。使用直接移交将更高效,因为任务会直接移交给执行它的线程,而不是被放在队列中,然后由工作线程从队列中提取任务。只有当线程池是无界的或者可以拒绝任务时,该队列才有实际价值。Executors. newCachedThreadPool使用了该队列。
PriorityBlockingQueue:具有优先级的无界队列,按优先级对元素进行排序。元素的优先级是通过自然顺序或 Comparator 来定义的。
4.拒绝策略
new ThreadPoolExecutor. CallerRunsPolicy ( )
5. 执行流程
先使用核心线程池处理任务,多余的任务放入阻塞队列中,队列满后使用救急线程,当线程数达到最大线程数后,使用拒绝策略
6.如何合理的配置线程池的最大线程数?
先判断是CPU密集型还是IO密集型
CPU密集型,设置线程数 = CPU数 + 1 ,通常能实现最优的利用率
Runtime. getRuntime ( ) . availableProcessors ( )
IO密集型,设置 线程数 = CPU数 * 2