1、创建固定大小的线程池:
- 固定大小: 这是一个固定大小的线程池,其中线程的数量始终保持在指定的大小(10个线程)。这意味着它不会在执行任务的时候动态地增加或减少线程的数量。
- 任务队列: 任务队列采用无界的
LinkedBlockingQueue
,这意味着它可以保存无限多的等待执行的任务。当线程池的所有线程都在执行任务时,新的任务会被放入队列中等待执行。(容易OOM ,please not use!) - 核心线程一直存活: 核心线程数是指线程池中一直存活的线程数量。在这个固定大小的线程池中,这些核心线程会一直存活,不会因为空闲而被回收。
- 无超时机制: 因为是固定大小的线程池,所以没有线程超时机制,即线程在执行完任务后不会被立即回收,而会一直保持存活状态。
ExecutorService executor = Executors.newFixedThreadPool(10);
ExecutorService executor = Executors.newFixedThreadPool(
5,
new ThreadFactory() {
private final String poolName = "CustomPoolThread";
private AtomicInteger count = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setName(poolName + "-" + count.getAndIncrement());
return thread;
}
}
);
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
2、创建单线程池
ExecutorService executor = Executors.newSingleThreadExecutor();
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
- 单线程执行: 这个线程池只有一个工作线程。所有提交到这个线程池的任务都会在同一个线程中按顺序执行,保证了任务的顺序性。如果任务执行失败而终止那么没有任何补救措施,而线程池还会新建一个线程,保证池的正常工作。
- 任务队列: 使用无界的任务队列,即
LinkedBlockingQueue
。这意味着可以接受无限多的任务,这些任务会按照先进先出(FIFO)的顺序被执行。 - 核心线程一直存活: 即使没有任务执行,单线程池的核心线程会一直存活,不会被回收。
- 线程超时机制: 对于没有任务执行的线程,经过一定时间(默认是60秒)会被回收,以释放资源。
- 适用场景: 适用于需要保持任务执行顺序、有序执行的场景,比如需要顺序执行的后台任务、定时任务等。
3、可缓存的线程池
-
动态线程数量: 这个线程池的线程数量是不固定的,会根据需要动态增加或减少。如果有空闲线程,将会被重用,否则会创建新的线程。
-
任务队列: 使用
SynchronousQueue
作为任务队列,这是一个没有容量的队列,每个任务都会触发创建新线程,或者使用现有的空闲线程。 -
核心线程空闲时间: 线程池中的线程在空闲时间超过60秒时会被终止并移出池。
-
适用场景: 适用于大量短时间的任务,不断变化的任务数,例如处理临时任务、异步操作等。
-
SynchronousQueue: 实现特点是,它没有容量,没有线程来取是放不进去的。它的插入操作(
put
方法)必须等待另一个线程的对应删除操作(take
方法)
ExecutorService executor = Executors.newCachedThreadPool();
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
4、定时任务线程池
-
定时任务执行: 这个线程池可以执行定时任务和周期性任务。你可以使用
schedule
方法来执行定时任务,使用scheduleAtFixedRate
或scheduleWithFixedDelay
方法执行周期性任务。 -
线程数量: 这是一个固定大小的线程池,有5个线程,用于执行任务。
-
任务队列: 使用
DelayedWorkQueue
作为任务队列,用于存放定时和周期性任务。 -
核心线程一直存活: 即使没有任务执行,线程池的核心线程会一直存活,不会被回收。
-
适用场景: 适用于需要定时执行或者周期性执行任务的场景,比如定时任务调度、定时检查等。
ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(5);
// 定时任务,延迟1秒执行
scheduledExecutor.schedule(() -> {
System.out.println("Task 1 executed after 1 second");
}, 1, TimeUnit.SECONDS);
// 周期性任务,延迟2秒开始执行,每3秒执行一次
scheduledExecutor.scheduleAtFixedRate(() -> {
System.out.println("Task 2 executed every 3 seconds");
}, 2, 3, TimeUnit.SECONDS);
// 关闭线程池
scheduledExecutor.shutdown();