线程池执行流程
ThreadPoolExecutor 关键节点的执行流程如下:
-
当线程数小于核心线程数时,创建线程。
-
当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
-
当线程数大于等于核心线程数,且任务队列已满:若线程数小于最大线程数,创建线程;若线程数等于最大线程数,(默认拒绝策略)抛出异常,拒绝任务。
1. 通过Executors创建线程池
创建固定线程的线程池,采用队列缓存线程的模式,但是队列中没有设置最大值,默认是int的最大值,这样会导致内存问题。
Executors.newFixedThreadPool(5).submit(() -> System.out.println(Thread.currentThread().getName()));
2. 通过newCachedThreadPool创建线程池
创建带缓存的线程池,适用于短期有大量的任务场景,线程数根据任务数量来创建。即有多少任务则创建多少线程。
Executors.newCachedThreadPool().submit(()-> System.out.printf(Thread.currentThread().getName()));
3. 通过newSingleThreadExecutor创建单个线程的线程池
corePoolSize为1,maximumPoolSize为1,keepAliveTime为0,阻塞队列使用的是LinkedBlockingQueue
Executors.newSingleThreadExecutor().submit(()-> System.out.println(Thread.currentThread().getName()));
4. 通过newSingleThreadScheduledExecutor创建执行定时任务的当个线程的线程池,线程将会在3s后执行
Executors.newSingleThreadScheduledExecutor()
.schedule(()-> System.out.println(Thread.currentThread().getName()),
3, TimeUnit.SECONDS);
5. 通过newScheduledThreadPool创建执行定时任务的线程
Executors.newScheduledThreadPool(5).schedule(() -> System.out.println(Thread.currentThread().getName()), 3, TimeUnit.SECONDS);
// 执行多次任务,当执行多个任务时会在上一个线程结束3s后执行下一个任务
Executors.newScheduledThreadPool(5).scheduleWithFixedDelay(() -> System.out.println(Thread.currentThread().getName()), 3, 2, TimeUnit.SECONDS);
6. 通过newWorkStealingPool根据系统自动配置生成线程池
Executors.newWorkStealingPool().submit(() -> System.out.println(Thread.currentThread().getName()));
7. 手动创建线程池
//线程工厂
ThreadFactory factory = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
return thread;
}
};
new ThreadPoolExecutor(
2,
3,
3, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
factory
//1.提示异常,拒绝执行多余的任务
// new ThreadPoolExecutor.AbortPolicy()
//2.忽略堵塞队列中最旧的任务
//new ThreadPoolExecutor.DiscardOldestPolicy()
//3.忽略最新的任务
//new ThreadPoolExecutor.DiscardPolicy()
//4.使用调用该线程池的线程来执行任务
//new ThreadPoolExecutor.CallerRunsPolicy()
//5.A自定义拒绝策略
);
代码示例
package cn.unuuc.pool;
import java.util.concurrent.*;
/**
* 创建线程池的7中方法
*/
public class MainApp {
public static void main(String[] args) {
// 1. 通过Executors创建线程池
Executors.newFixedThreadPool(5).submit(() -> System.out.println(Thread.currentThread().getName()));
// 2. 创建带缓存的线程池,适用于短期有大量的任务场景,线程数根据任务数量来创建
Executors.newCachedThreadPool().submit(()-> System.out.printf(Thread.currentThread().getName()));
// 3. 创建单个线程的线程池
Executors.newSingleThreadExecutor().submit(()-> System.out.println(Thread.currentThread().getName()));
// 4. 创建执行定时任务的当个线程的线程池,线程将会在3s后执行
Executors.newSingleThreadScheduledExecutor()
.schedule(()-> System.out.println(Thread.currentThread().getName()),
3, TimeUnit.SECONDS);
// 5. 创建执行定时任务的线程
Executors.newScheduledThreadPool(5).schedule(() -> System.out.println(Thread.currentThread().getName()), 3, TimeUnit.SECONDS);
// 执行多次任务,当执行多个任务时会在上一个线程结束3s后执行下一个任务
Executors.newScheduledThreadPool(5).scheduleWithFixedDelay(() -> System.out.println(Thread.currentThread().getName()), 3, 2, TimeUnit.SECONDS);
// 6. 根据系统自动配置生成线程池
Executors.newWorkStealingPool().submit(() -> System.out.println(Thread.currentThread().getName()));
// 7. 手动创建线程池
//线程工厂
ThreadFactory factory = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
return thread;
}
};
new ThreadPoolExecutor(
2,
3,
3, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
factory
//1.提示异常,拒绝执行多余的任务
// new ThreadPoolExecutor.AbortPolicy()
//2.忽略堵塞队列中最旧的任务
//new ThreadPoolExecutor.DiscardOldestPolicy()
//3.忽略最新的任务
//new ThreadPoolExecutor.DiscardPolicy()
//4.使用调用该线程池的线程来执行任务
//new ThreadPoolExecutor.CallerRunsPolicy()
//5.A自定义拒绝策略
);
}
}
评论区