线程池ThreadPoolExecutor使用

本文详细介绍了Java中线程池的创建方式及工作原理,包括可缓存线程池、定长线程池、定时线程池和单一线程池等。通过分析不同类型的线程池如何处理任务,帮助读者理解线程池的配置参数及其作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程池可以通过Executors快捷的创建。

创建可缓存的线程池,线程数可以无限多。

ExecutorService service1 = Executors.newCachedThreadPool();

创建定长的线程池。

ExecutorService service2 = Executors.newFixedThreadPool(10);

创建定长的线程池,可定时周期执行。

ExecutorService service3 = Executors.newScheduledThreadPool(10);

创建单一线程的线程池。

ExecutorService service4 = Executors.newSingleThreadExecutor();


为了便于理解,看下内部创建的方式:

public static ExecutorService newCachedThreadPool() {
	return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue());
}
public static ExecutorService newFixedThreadPool(int paramInt) {
	return new ThreadPoolExecutor(paramInt, paramInt, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
}

创建线程池参数:

ThreadPoolExecutor pool = new ThreadPoolExecutor(1, // coreSize,核心线程数
				2, // MaxSize,最大线程数
				60, // 60,线程空闲的时间,超过时间,则会被销毁
				TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3) // 指定一种队列,存放任务待处理。
																		// (有界队列)
				// new LinkedBlockingQueue<Runnable>()
				, new MyRejected()// 拒绝策略
		);


pool中添加任务数为1,因为核心线程为1,会被立即执行。

pool中添加任务数为2/3/4,因为核心线程为1,会被放到队列中等待执行。

pool中添加任务数为5,因为核心线程为1,队列为3,此时核心线程正在执行,且队列已经满了,但是max为2,所以会启动一个新的线程执行任务5。(此时如果1还没有执行完,那么5会优先2/3/4执行)。

pool中添加任务数为6,因为核心线程为1,队列为3,此时核心线程正在执行,且队列已经满了,且max为2,此时任务6不知道既没线程去执行,又没有队列存储,只能走拒绝策略。

整体的顺序,添加任务时首先看核心线程还有没有,有就立即执行,没有就放到队列中等待,当队列满了,就看max-core线程数还有没有空间,如果有就立即启动线程执行,没有就走拒绝策略。

当队列采用LinkedBlockingQueue这种无界队列时,max就没有用了,因为超过core的任务会放到队列中等待执行。


所以可以看到newCachedThreadPool的创建方式:


core为0,max为Integer最大值,空闲存活时间为60s,队列为没有空间的SynchronousQueue,此时可以知道,这个队列是没用的,任务全部会执行。

再看下newFixedThreadPool的创建方式:


core和max都为我们设置的固定大小的线程数,队列是无界队列,即最大可以同时运行我们设置的任务数。

newScheduledThreadPool的创建方式,可定时执行的原因是因为队列使用的是DelayedWorkQueue(对DelayQueue的优化



newSingleThreadExecutor的创建方式,单一线程:


Java线程池ThreadPoolExecutor是Java提供的一个用于管理和复用线程的工具类。它可以帮助我们更有效地管理线程资源,提高程序的性能和可维护性。 下面是一个简单的使用ThreadPoolExecutor的示例代码: ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolExample { public static void main(String[] args) { // 创建一个线程池,其中包含5个线程 ExecutorService executor = Executors.newFixedThreadPool(5); // 提交任务给线程池执行 for (int i = 0; i < 10; i++) { Runnable worker = new WorkerThread("Task " + i); executor.execute(worker); } // 关闭线程池 executor.shutdown(); while (!executor.isTerminated()) { // 等待所有任务完成 } System.out.println("所有任务已完成"); } } class WorkerThread implements Runnable { private String taskName; public WorkerThread(String taskName) { this.taskName = taskName; } @Override public void run() { System.out.println(Thread.currentThread().getName() + " 开始执行任务:" + taskName); try { // 模拟任务执行时间 Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 完成任务:" + taskName); } } ``` 上述代码中,首先通过`Executors.newFixedThreadPool(5)`创建了一个包含5个线程的线程池。然后使用`executor.execute(worker)`提交任务给线程池执行,其中`worker`是实现了`Runnable`接口的任务对象。任务会被线程池中的线程异步执行。 最后,通过`executor.shutdown()`关闭线程池,并使用`executor.isTerminated()`等待所有任务完成。完成后输出"所有任务已完成"。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值