JDK的线程池,它是预先创建好一些线程,放在池中。用的时候从池中取线程,用完放回池中。
避免了创建,销毁线程的开销。与数据库连接池是同样的道理。
1.固定数量的线程池 newFixedThreadPool
作用:这是一个线程数固定的,线程可以重用的线程池,用共享的无界队列方式运行这些线程。
如果所有的核心线程都在忙,这时又有新的任务来,这个新的任务会去队列中等待。
如果一个线程在半路突然中止了,那么会有一个新的线程代替它执行后续的任务。
一个线程在被关闭之前,它会一直在线程池中等待被调用。(下班前,要一直在公司等着干活,不能回家)
特征:
1.线程池中线程的量固定,可以控制线程的并发量。
2.线程可以被重复利用
3.任务数超出核心线程数时,那些额外的任务需要去队列中等待。如果队列中都挤满了,又有新的任务来,就会派额外的新线程去接客。如果达到了最大线程数后,还有新的任务来,那就直接抛异常吧,干不了了。
创建方式:
1.Executors.newFixedThreadPool(int nThreads); //参数为线程的总数
2.Executors.newFixedThreadPool(int nThreads,ThreadFactory threadFactory); //参数为线程的总数 和 创建线程的工厂
通过看底层源码发现,这种线程池最终是通过实例化ThreadPoolExecutor来实现的。
ThreadPoolExecutor的构造方法有很多参数:
- corePoolSize:核心线程数
- maxImumPoolSize:最大线程数 (如果它和核心线程数相等时,即没有后备外援了,如果此时队列中的任务也满了,如果再有任务来,就抛异常)
- keepAliveTime: 是指那些后备外援线程的 最大存活时间。
- unit:时间单位
- workQueue:工作队列,存放要执行的任务的地方。
- threadFactory:创建线程的工厂
还有一个Handler,拒绝策略。
拒绝策略有4种:
1.AbortPolicy:这个比较简单粗暴,直接抛出异常,也是默认的拒绝策略。(上面构造方法中的defaultHandler就指的是它)
2.CallerRunsPolicy:直接在调用线程中执行该任务。
3.DiscardPolicy:直接将该任务丢弃。
4.DiscardOldestPolicy:丢弃最老的未被执行的任务,这样队列中就有地方了,把这个新任务放到队列中
2.缓存线程池 newCachedThreadPool
作用:它是根据需要,创建线程,没有核心线程,当60s内这个线程没接收到任务时,它就会被从池中收走。60s内这个线程又接收到新任务时,它就又被重用了。
特征:
1.线程池中线程的数量不固定,最大值是Integer的最大值
2.池中的线程干完活后会等待1分钟(默认的),如果1分钟内又有新任务,这个线程就被调用去干新任务了,如果等了1分钟还没有新任务,这个线程就被从池中清理出去了。
3.当池中没有可用线程时,就创建一个新线程。
创建方式:
1.Executors.newCachedThreadPool();
3.只有一个线程的线程池 newSingleThreadPool
作用:这个线程池中只有1个线程,用无界队列的方式运行。如果这个线程突然挂掉了,线程池会新建一个新的线程顶替它,继续完成任务。
特征:池中只有1个线程,任务要在队列中排队。当需要保证任务执行顺序时,适合用它。
创建方式:
1.Executors.newSingleThreadExecutor();
2.Executors.newSingleThreadExecutor(ThreadFactory threadFactory);
4.延时线程池 newScheduleThreadPool
作用:创建一个线程池,可以让它里面的线程延迟执行,或在规定的时间后执行。
特征:
1.这个池中的线程,可以让它们延迟干活,或规定时间干活(不用来一个任务就去干)
2.线程池中的线程数量固定,即使没有任务,这些线程也保留。(没活也得待在公司)
创建方法:
1.Executors.newScheduledThreadPool(int corePoolSize);
2.Executors.newScheduledThreadPool(int corePoolSize,ThreadFactory threadFactory);
5. 并行线程池 newWorkStealingPool
作用:jdk1.8提供的线程池,底层使用ForkJoinPool实现,池中有多个任务队列。适用于任务多,可以并发执行的场景。
特征:池中有多个队列
创建方法:
Executors.newWorkStealingPool(int parallelism) 参数的意思是:队列的数量
这个大佬总结的很好:
https://blog.csdn.net/u012253957/article/details/102966939