mport java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.*;
/**
* 一, 线程池: 提供了一个线程队列,队列中保存着等待状态的线程,避免了频繁的创建和销毁线程造成的额外开销,提高了相应速度.
* 二, 线程池体系结构:
* java.util.concurrent.Executor: 负责线程使用与调度的根接口
* |-- **ExecutorService 子接口 : 线程池的主要接口
* |-- ThreadPoolExecutor 线程池的实现类
* |-- ScheduledExecutorService 子接口: 负责线程的调度
* |-- ScheduledThreadPoolExecutor : 继承 ThreadPoolExecutor,实现ScheduledExecutorService
*
* 三,工具类: Executors
* ExecutorService newFixedThreadPool(); : 创建固定大小的线程池(等待线程的队列的最大值为int的最大值)
* ExecutorService newCachedThreadPool(); : 缓存线程池,线程池中的线程数量不固定,可以根据需求自动的更改数量.(线程的最大数量为int的最大值)
* ExecutorService newSingleThreadPool(); : 创建单个线程的线程池,池中只有一个线程.
*
* ScheduledExecutorService newScheduledThreadPool(); : 创建固定大小的线程,可以延迟或定时的执行任务.
*/
public class ThreadPoolDemo {
/**
* 项目中通常是直接创建ThreadPoolExecutor的实例,参数详解如下
* public ThreadPoolExecutor(int corePoolSize,//核心线程数,即使空闲也保留在线程中的线程数,除非设置allowCoreThreadTimeOut
* // CPU核数 = Runtime.getRuntime().availableProcessors();
* // (一般配置规律:CPU密集型:核心线程数 = CPU核数 + 1,IO密集型:核心线程数 = CPU核数 * 2)
* int maximumPoolSize,// 池中允许的最大线程数
* long keepAliveTime,// 当线程数大于内核时,这是多余的空闲线程在终止前等待新任务的最大的时间
* TimeUnit unit,// keepAliveTime的时间单位
* BlockingQueue<Runnable> workQueue,// 用于在执行任务之前使用的队列,这个队列将仅保存execute方法提交的Runnable任务
* ThreadFactory threadFactory,// 执行程序创建新线程时使用的工厂(通常用来给线程赋名称值)
* RejectedExecutionHandler handler);// 线程拒绝策略(达到线程限制或队列已满)
*
*/
/*
接下来说说线程池的拒绝策略 :
JDK实现的拒绝有四种:
1, AbortPolicy : 该策略会直接抛异常,阻止系统正常工作
2,CallerRunsPolcy: 如果线程池已经关闭则丢弃当前任务,只要线程池没有关闭,就直接在execute方法的调用线程中运行被拒绝的任务,
虽然减少了任务丢弃的几率,但是任务提交线程的性能将很可能急剧下降.
3,DiscardOldestPolicy: 如果线程池已经关闭则丢弃当前任务,否则就丢弃最旧的未处理的任务,然后重试execute方法.
4,DiscardPolicy: 默默的丢弃没法处理的任务,如果允许线程任务丢失则可采用该拒绝策略.
最后还有一种自定义的拒绝策略
5,自定义的拒绝策略: 实现RejectedExecutionHandler接口 并重写其中的rejectedExecution()方法.参数r为任务线程,executor为当前线程池.
(默认拒绝策略源码如下)
//The default rejected execution handler
private static final RejectedExecutionHandler defaultHandler =
new AbortPolicy();
线程池的默认拒绝策略为 AbortPolicy
*/
public static void main(String[] args) throws Exception{
// 测试调度线程池
ScheduledExecutorService excutor = Executors.newScheduledThreadPool(4);
ArrayList<ScheduledFuture<Integer>> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) {
ScheduledFuture<Integer> schedule = excutor.schedule(() -> {
int num = new Random().nextInt(100);
System.out.println(Thread.currentThread().getName()+" : "+num);
return num;
}, 1, TimeUnit.SECONDS);// 延迟一秒执行任务
futures.add(schedule);
}
excutor.shutdown();// 以平和的方式关闭线程池(等池中的线程执行完毕之后再关闭线程池)
// excutor.shutdownNow()// 暴力关闭线程池
for (ScheduledFuture<Integer> future : futures) {
System.out.println(future.get());
}
}
}
线程池知识点整理
最新推荐文章于 2023-09-13 08:30:00 发布