
例子:
10年前单核CPU电脑,假的多线程,像马戏团小丑玩多个球,CPU需要来回切换。
现在是多核电脑,多个线程各自跑在独立的CPU上,不用切换效率高。
线程池的优势:
线程池做的工作只要是控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等其他线程执行完毕,再从队列中取出任务来执行。
它的主要特点为:线程复用;控制最大并发数;管理线程。
第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的销耗。
第二:提高响应速度。当任务到达时,任务可以不需要等待线程创建就能立即执行。
第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会销耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

第一种
Executors.newFixedThreadPool(10); 初始化线程池的大小.

第二种
Executors.newSingleThreadExecutor(); 一池,一线程!

第三种
Executors.newCachedThreadPool(); 执行异步短期任务,可扩容.

三种创建线程池的方式:底层都是new ThreadPoolExecutor();
用线程池:使用哪一种?都不用!
自定义线程池:
new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
1、corePoolSize:线程池中的常驻核心线程数
2、maximumPoolSize:线程池中能够容纳同时执行的最大线程数,此值必须大于等于1
3、keepAliveTime:多余的空闲线程的存活时间,当前池中线程数量超过corePoolSize时,当空闲时间达到keepAliveTime时,多余线程会被销毁直到只剩下corePoolSize个线程为止
4、unit:keepAliveTime的单位
5、workQueue:任务队列,被提交但尚未被执行的任务
6、threadFactory:表示生成线程池中工作线程的线程工厂,用于创建线程,一般默认的即可
7、handler:拒绝策略,表示当队列满了,并且工作线程大于等于线程池的最大线程数(maximumPoolSize)时如何来拒绝请求执行的runnable的策略


以下内置拒绝策略均实现了RejectedExecutionHandle接口
1.AbortPolicy(默认):直接抛出RejectedExecutionException异常阻止系统正常运行
2.CallerRunsPolicy:“调用者运行”一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量。
3.DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加人队列中尝试再次提交当前任务。
4.DiscardPolicy:该策略默默地丢弃无法处理的任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一种策略。
超级大坑
答案:是一个都不用,我们工作中只能使用自定义的
Executors中JDK已经给你提供了,为什么不用?

解释FixedThreadPool 和 SingleThreadPool:
相当于核心线程数就等于最大线程池数,可能会导致堆积大量的请求


解释CachedThreadPool
会创建大量的线程

```csharp
public class MyThreadPoolDemo {
public static void main(String[] args) {
//自定义线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
2, //核心线程池
5, //最大线程池
3L, //空闲线程的存活时间
TimeUnit.SECONDS, //空闲线程存活时间单位
new ArrayBlockingQueue<>(3), //阻塞队列个数
Executors.defaultThreadFactory(), //使用默认的工厂值
// new ThreadPoolExecutor.AbortPolicy() //默认值:直接发生异常,组织运行
// new ThreadPoolExecutor.DiscardOldestPolicy() //抛弃等待最久的任务,尝试加入新的任务
// new ThreadPoolExecutor.CallerRunsPolicy() //调用者执行任务
new ThreadPoolExecutor.DiscardPolicy()
);
//银行处理业务:10个顾客来办理业务!
//暂时处理6个顾客
try {
for (int i = 1; i <= 10 ; i++) {
threadPoolExecutor.execute(()->{
System.out.println(Thread.currentThread().getName()+"\t 处理业务");
});
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
threadPoolExecutor.shutdown();
}
}
}