线程池的使用在Java多线程编程经常使用,以下 7 种创建线程池的使用方式,下面我一一来详解@mikechen
1.创建一个固定大小的线程池
这种方式会创建一个固定大小的线程池,当有新的任务提交时,如果线程池中有空闲的线程,就会使用这些线程来执行任务。
如下所示:
ExecutorService executor = Executors.newFixedThreadPool(5); for (int i = 0; i < 10; i++) { executor.execute(new MyTask(i)); } executor.shutdown();
2.创建一个只有一个线程的线程池
这种方式会创建一个只有一个线程的线程池,所有提交的任务都将在这个线程中执行。这种方式通常用于需要顺序执行任务的场景。
如下所示:
ExecutorService executor = Executors.newSingleThreadExecutor(); for (int i = 0; i < 10; i++) { executor.execute(new MyTask(i)); } executor.shutdown();
3.创建⼀个可缓存的线程池
newCachedThreadPool:创建⼀个可缓存的线程池,若线程数超过处理所需,缓存⼀段时间后会回收,若线程数不够则新建线程。
如下所示:
ExecutorService executor = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { executor.execute(new MyTask(i)); } executor.shutdown();
4.创建定时周期固定的线程池
newScheduledThreadPool(int n) 创建一个固定大小的线程池,其中包含 n 个线程,可以用来执行定时或周期性任务。
如下所示:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5); executor.schedule(new MyTask(1), 5, TimeUnit.SECONDS); executor.scheduleAtFixedRate(new MyTask(2), 1, 5, TimeUnit.SECONDS); executor.shutdown();
5.创建定时或周期性任务的单个线程池
newSingleThreadScheduledExecutor() 创建一个只有一个线程的线程池,可以用来执行定时或周期性任务。
如下所示:
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); executor.schedule(new MyTask(1), 5, TimeUnit.SECONDS); executor.scheduleAtFixedRate(new MyTask(2), 1, 5, TimeUnit.SECONDS); executor.shutdown();
6.创建工作窃取线程池
newWorkStealingPool() 创建一个工作窃取线程池,其中每个线程都维护自己的任务队列,当一个线程执行完自己的任务队列中的任务后,就会从其他线程的任务队列中窃取任务来执行。
如下所示:
ExecutorService executor = Executors.newWorkStealingPool(); for (int i = 0; i < 10; i++) { executor.execute(new MyTask(i)); } executor.shutdown();
7.最原始的创建线程池的⽅式
可以通过ThreadPoolExecutor 手动创建线程池,这也是阿里等大厂推荐使用方式。
如下所示:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
构造器七个参数:
- corePoolSize:线程池中的常驻核心线程数;
- maximumPoolSize:线程池中能够容纳同时执行的最大线程数,此值必须大于等于1;
- keepAliveTime:多余的空闲线程的存活时间;
- unit:keepAliveTime的时间单位;
- workQueue:任务队列,被提交但尚未被执行的任务;
- threadFactory:表示生成线程池中工作线程的工厂, 用于创建线程,一般默认的即可;
- handler:拒绝策略处理器,任务将按照某个既定的拒绝策略被拒绝执行。
以上就是7种常见的线程池的使用方式,更多线程池,请查看:线程池超详解(原理流程参数及创建使用)
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》