池化技术
程序运行的本质:占用系统资源! 池化技术目的是优化资源利用!
线程池 连接池 内存池 对象池 等等
池化技术:事先准备好一组资源,需要来拿,用完归还到池中
- 最小值
- 最大值
- 默认值
线程池的好处:
- 降低资源消耗
- 提高响应速度
- 方便监控管理
总结:线程复用 控制最大并发数 管理线程
线程池不允许通过 Executors 创建,而是通过 ThreadPoolExecutor 的方式创建,这样的处理方式
可以让开发者更加明确线程池的运行规则,避免资源耗尽的风险。
Executors 返回的线程池对象的弊端如下:
- FixedThreadPool 和 SingleThreadPool:
允许的请求队列长度为Integer.MAX_VALUE
, 可能会积累大量请求进而OOM - CachedThreadPool 和 ScheduledThreadPool:
允许的创建线程数量为Integer.MAX_VALUE
, 可能会创建大量线程进而OOM
线程池:三大方法、7大参数、4种拒绝策略
三大方法
7大参数
public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小
int maximumPoolSize, // 最大核心线程池大小
long keepAliveTime, // 超时未调用就会释放
TimeUnit unit, // 超时单位
BlockingQueue<Runnable> workQueue, // 阻塞队列
ThreadFactory threadFactory, // 线程工厂 创建线程用 一般不动
RejectedExecutionHandler handler // 拒绝策略) {
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;
}
4种拒绝策略
new ThreadPoolExecutor.AbortPolicy() // 拒绝 抛出异常
new ThreadPoolExecutor.DiscardPolicy() // 拒绝 无异常抛出
new ThreadPoolExecutor.CallerRunsPolicy() // 从哪里来到哪里去 无异常抛出
ThreadPoolExecutor.DiscardOldestPolicy() // 尝试和第一个竞争 无异常抛出
池化技术
程序的运行,本质:用系统的资源!优化资源的使用! =>池化技术
线程池、连接池、内存池、对象。./…
池化技术:事先准备好一些资源,有人要用,就来我这里拿,院之后还给我。
线程池的好处: .
-
降低资源的消耗
-
提高响应的速度
-
方便管理。
线程复用、可以控制最大并发數、管理线程
线程池: 三大方法
ExecutorService threadPool = Executors . newsingleThreadExecutor();//单个线程
ExecutorService threadPool = Executors . newFixedThreadPool(5); //创建- - -个固定的线程池的大小
ExecutorService threadPool = Executors . newCachedThreadPool(); //可伸缩的,遇强则强,遇弱则弱
try {
for(inti=0;i<100;i++){
///使用了线程池之后,使用线程池来创建线程
threadPoo1l. execute(()->{
System. out . print1n(Thread. currentThread() . getName()+" ok");
});
}
7大参数
源码分析
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public ThreadPoolExecutor(int corePoolSize, // 核心线程池的大小
int maximumPoolSize, // 最大核心线程池大小
long keepAliveTime, // 超时释放
TimeUnit unit, // 超时单位
BlockingQueue<Runnable> workQueue, // 阻塞队列
ThreadFactory threadFactory, // 线程工程(不用动)
RejectedExecutionHandler handler) { // 拒绝策略
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;
}
创建一个线程池
public class Demo01 {
public static void main(String[] args) {
// 自定义线程池!工作 ThreadPoolExecutor
// 最大线程到底该如何定义
// 1、CPU 密集型,几核,就是几,可以保持CPu的效率最高!
// 2、IO 密集型 > 判断你程序中十分耗IO的线程,
// 程序 15个大型任务 io十分占用资源!
// 获取CPU的核数
System.out.println(Runtime.getRuntime().availableProcessors());
List list = new ArrayList();
ExecutorService threadPool = new ThreadPoolExecutor(
2,
Runtime.getRuntime().availableProcessors(),
3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(3),
Executors.defaultThreadFactory(),
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();
}
}
}
四种拒绝策略
/**
* new ThreadPoolExecutor.AbortPolicy() // 银行满了,还有人进来,不处理这个人的,抛出异常
* new ThreadPoolExecutor.CallerRunsPolicy() // 哪来的去哪里!
* new ThreadPoolExecutor.DiscardPolicy() //队列满了,丢掉任务,不会抛出异常!
* new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试去和最早的竞争,也不会抛出异常!
*/