3大方法、7大参数、4种拒绝策略
池化技术
程序的运行,本质:占用系统的资源! (优化资源的使用 => 池化技术)
线程池、连接池、内存池、对象池///… 创建、销毁。十分浪费资源
池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我。
线程池好处
1、降低系统资源的消耗
2、提高响应的速度
3、方便管理
4、线程复用、可以控制最大并发数、管理线程
三大方法
import java.util.concurrent.ExecutorService;
import java.util.List;
import java.util.concurrent.Executors;
public class Demo01 {
public static void main(String[] args) {
// Executors 工具类、3大方法
// Executors.newSingleThreadExecutor();// 创建单个线程的线程池
// Executors.newFixedThreadPool(5);// 创建一个固定大小的线程池
// Executors.newCachedThreadPool();// 创建一个可伸缩的线程池
// 单个线程的线程池
ExecutorService threadPool =
Executors.newSingleThreadExecutor();
try {
for (int i = 1; i < 100; i++) {
// 使用了线程池之后,使用线程池来创建线程
threadPool.execute(()->{
System.out.println(
Thread.currentThread().getName()+" ok");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 线程池用完,程序结束,关闭线程池
threadPool.shutdown();
}
}
}
newSingleThreadExecutor() 创建单个线程的线程池
newFixedThreadPool(5) 创建一个固定大小的线程池
newCachedThreadPool(); 创建一个可伸缩的线程池
7大参数
源码分析中
// 本质ThreadPoolExecutor()
public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小
int maximumPoolSize, // 最大核心线程池大小
long keepAliveTime, // 超时没有人调用就会释放
TimeUnit unit, // 超时单位
// 阻塞队列
BlockingQueue<Runnable> workQueue,
// 线程工厂:创建线程的,一般 不用动
ThreadFactory threadFactory,
// 拒绝策略
RejectedExecutionHandler handle ) {
if (corePoolSize < 0
|| maximumPoolSize <= 0
|| maximumPoolSize < corePoolSize
|| keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null
|| threadFactory == null
|| handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null
? null : AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
因为实际开发中工具类Executors 不安全,所以需要手动创建线程池,自定义7个参数。
Executors 在FixedThreadPool 和 SingleThreadPool中 允许的请求队列长度为integer.MAX_VALUE
== 时,会出现大量堆积请求,从而导致OOM(内存溢出) ==
在CachedThreadPool 和 ScheduledThreadPool中 允许的创建线程数量为integer.MAX_VALUE时,
== 会出现大量堆积请求,从而导致OOM(内存溢出) ==
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
// Executors 工具类、3大方法
// Executors.newSingleThreadExecutor();// 创建一个单个线程的线程池
// Executors.newFixedThreadPool(5);// 创建一个固定大小的线程池
// Executors.newCachedThreadPool();// 创建一个可伸缩的线程池
/**
* 四种拒绝策略:
*
* new ThreadPoolExecutor.AbortPolicy()
* 银行满了,还有人进来,不处理这个人的,抛出异常
*
* new ThreadPoolExecutor.CallerRunsPolicy()
* 哪来的去哪里!比如你爸爸正在做的饭 让你去通知妈妈做饭,妈妈拒绝,让你回去通知爸爸做饭,就是交给原来线程处理
*
* new ThreadPoolExecutor.DiscardPolicy()
* 队列满了,丢掉任务,不会抛出异常!
*
* new ThreadPoolExecutor.DiscardOldestPolicy()
* 队列满了,尝试去和最早的竞争,也不会抛出异常!
*/
public class Demo01 {
public static void main(String[] args) {
// 自定义线程池!工作 ThreadPoolExecutor
ExecutorService threadPool = new ThreadPoolExecutor(
2,// int corePoolSize, 核心线程池大小(候客区窗口2个)
5,// int maximumPoolSize, 最大核心线程池大小(总共5个窗口)
3,// long keepAliveTime, 超时3秒没有人调用就会释,放关闭窗口
TimeUnit.SECONDS,// TimeUnit unit, 超时单位 秒
new LinkedBlockingDeque<>(3),// 阻塞队列(候客区最多3人)
Executors.defaultThreadFactory(),// 默认线程工厂
// 4种拒绝策略之一:
// 队列满了,尝试去和 最早的竞争,也不会抛出异常!
new ThreadPoolExecutor.DiscardOldestPolicy());
//队列满了,尝试去和最早的竞争,也不会抛出异常!
try {
// 最大承载:Deque + max
// 超过 RejectedExecutionException
for (int i = 1; i <= 9; i++) {
// 使用了线程池之后,使用线程池来创建线程
threadPool.execute(()->{
System.out.println(
Thread.currentThread().getName()+" ok");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 线程池用完,程序结束,关闭线程池
threadPool.shutdown();
}
}
}
4种拒绝策略
- new ThreadPoolExecutor.AbortPolicy()
- 银行满了,还有人进来,不处理这个人的,抛出异常
- new ThreadPoolExecutor.CallerRunsPolicy()
- 哪来的去哪里!比如你爸爸正在做的饭 让你去通知妈妈做饭,妈妈拒绝,让你回去通知爸爸做饭,就是交给原来线程处理
- new ThreadPoolExecutor.DiscardPolicy()
- 队列满了,丢掉任务,不会抛出异常!
- new ThreadPoolExecutor.DiscardOldestPolicy()
- 队列满了,尝试去和最早的竞争,也不会抛出异常!