目录
Ⅰ.SingleThreadExecutor():单线程线程池
Ⅱ newFixedThreadPool(int):固定数量线程池
Ⅲ newCachedThreadPool():可缓存线程池
一.封装好的线程池
Executors类:
Executors可以帮助快速实例化特定类型的线程池对象, Executors属于一个工具类, 返回值都是ExecutorService接口的实现类, 底层都是调用ThreadPoolExecutor()。
Ⅰ.SingleThreadExecutor():单线程线程池
-
构造方法参数:
-
corePoolSize和maximumPoolSize: 1
-
keepAliveTime: 0秒
-
unit: 微妙
-
workQueue: LinkedBlockingQueue
-
-
效果总结:
-
它只会创建一条工作线程处理任务;
-
采用的阻塞队列为LinkedBlockingQueue, 它是一个无界队列, 底层为链表。
-
Ⅱ newFixedThreadPool(int):固定数量线程池
1.构造方法参数:
① corePoolSize和maximumPoolSize: nTheads
②keepAliveTime: 0秒
③unit: 毫秒
④workQueue: LinkedBlockingQueue
2.效果总结:
①它是一种固定大小的线程池;
②corePoolSize和maximunPoolSize都为用户设定的线程数量nThreads;
③keepAliveTime为0,意味着一旦有多余的空闲线程,就会被立即停止掉;但这里keepAliveTime无效;
④阻塞队列采用了LinkedBlockingQueue,它是一个无界队列, 底层为链表;
⑤由于阻塞队列是一个无界队列,因此永远不可能拒绝任务;
⑥由于采用了无界队列,实际线程数量将永远维持在nThreads,因此maximumPoolSize和keepAliveTime将无效。
Ⅲ newCachedThreadPool():可缓存线程池
1.构造方法参数:
①corePoolSize: 0
②maximumPoolSize: Integer的最大值
③keepAliveTime: 60秒
④unit: 秒
⑤workQueue:SynchronousQueue
2.效果总结:
①它是一个可以无限扩大的线程池;
②它比较适合处理执行时间比较小的任务;
③corePoolSize为0,maximumPoolSize为无限大,意味着线程数量可以无限大;
④keepAliveTime为60S,意味着线程空闲时间超过60S就会被杀死;
3.采用SynchronousQueue(同步队列)装等待的任务,这个阻塞队列没有存储空间,这意味着只要有请求到来,就必须要找到一条工作线程处理他,如果当前没有空闲的线程,那么就会再创建一条新的线程。
Ⅳ newScheduledThreadPool(): 延时执行线程池
1.构造方法参数:
①corePoolSize: corePoolSize
②maximumPoolSize: Integer的最大值
③keepAliveTime: 10秒
④unit: 微妙
⑤workQueue:DeplayedWorkQueue
2.效果总结:
①它采用DelayQueue存储等待的任务
②它会根据time的先后时间排序,若time相同则根据sequenceNumber排序;
③DelayQueue也是一个无界队列;
④工作线程会从DelayQueue取已经到期的任务去执行;
⑤执行后也可以将任务重新定时, 放入队列中;
⑥支持定时, 周期性执行。
ⅤForkJoinPool线程池
1.介绍: ForkJoinPool是Java7新增的线程池类型。是ThreadPoolExecutor的兄弟类
* ForkJoinPool线程池
* 主要采用的思想就是分而治之
* 将多个拆分后的小任务分给不同的线程去执行(调用fork()方法)
* 最后将执行完的线程 合并到一起(调用join方法)
* 咱们关心的重点 就是一个大任务 分成多少个小任务
如果在分叉后一个线程执行完成,另外的线程还没有结束,会从双端队列中尾部处理任务,另一个线程从头部取任务,防止出现线程竞争
2. 使用方法
* 1. 我们在使用ForkJoinPool的时候 并不是直接使用它 而是使用它的子类
* RecursiveAction(不需要返回值的时候使用) & RecursiveTask(需要返回值的时候使用) 都是抽象类
* 这两个子类中 都有一个抽象方法 compute() 咱们在使用的时候 需要把compute方法重写一下就可以了
* 咱们的核心代码 就写在compute()方法中
* 2. 使用fork()执行子任务
* 使用join()方法将子任务合并成一个完整的任务
3.工作原理
* 工作原理: 工作窃取算法 主要目的也是为了提升性能 让多线程执行的速度更快
* 可以避免由于拆分了任务之后的join过长的等待
* 使用工作窃取算法最主要的目的: 就是某个线程执行完毕后 这个线程的任务队列中 没有任务时, 它可以
* 去其他线程的任务队列中拿到新的任务来执行,从而提升整个线程的性能
二.ThreadPoolExecutor: 自定义线程池
1.构造方法及参数类型: ![](https://i-blog.csdnimg.cn/blog_migrate/a8687cf4104f6af4bde6e2fff129de8d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ac2b424a0ba56c89316b9ce2c169365f.png)
2.代码示例:
public class Test {
public static void main(String[] args) {
//我们在使用自定义线程池的时候 核心线程数 不是乱写的 而是根据项目实际的日活量
// 服务器的内存 与 cpu性能 的综合情况 来设置核心线程数
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
//核心线程数 //最大线程数
5, 30000000,
//过期时间 //过期时间的单位
0L, TimeUnit.SECONDS,
//工作队列
new ArrayBlockingQueue<>(10));
for (int i = 0; i < 30; i++) {//创建了30个任务
int index = i;
threadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " == " + index);
}
});
}
threadPoolExecutor.shutdown();
}
}