线程池
线程池:三大方法
、7大参数
、4种拒绝策略
池化技术
事先准备好一些资源,要用的时候从池子中取,用完之后还回去
优点:
- 降低资源的消耗
- 提高响应速度
- 方便管理
三大方法
package com.sw.pool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @Author suaxi
* @Date 2021/2/14 21:23
*/
public class PoolTest {
public static void main(String[] args) {
//ExecutorService pool = Executors.newSingleThreadExecutor(); //单个线程
//ExecutorService pool = Executors.newFixedThreadPool(10); //创建一个固定大小的线程池
ExecutorService pool = Executors.newCachedThreadPool(); //线程池大小可弹性伸缩
try {
for (int i = 0; i < 50; i++) {
pool.execute(() -> {
System.out.println(Thread.currentThread().getName() + "--->Pool Test");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//线程池用完,程序结束,关闭线程池
pool.shutdown();
}
}
}
七大参数
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;
}
图片来源:狂神说Java
手动创建一个线程池
package com.sw.pool;
import java.util.concurrent.*;
/**
* @Author suaxi
* @Date 2021/2/14 21:23
* 4种拒绝策略:
* AbortPolicy() 线程池满了,还有人进来,不处理这个人的请求,同时抛出异常
* CallerRunsPolicy() 哪里来的请求,回到哪里去(请求对应的主方法)
* DiscardPolicy() 队列满了,丢掉后来的请求,不抛出异常
* DiscardOldestPolicy() 队列满了,尝试去和最早进行服务的窗口竞争,看那里的服务是否快要结束了,结束就进去提出请求,这种策略也不抛出异常
*/
public class ThreadPoolExecutorTest {
public static void main(String[] args) {
//自定义线程池
ExecutorService pool = new ThreadPoolExecutor(
2,
5,
3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardOldestPolicy());
try {
for (int i = 0; i < 50; i++) {
pool.execute(() -> {
System.out.println(Thread.currentThread().getName() + "--->Pool Test");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//线程池用完,程序结束,关闭线程池
pool.shutdown();
}
}
}
4种拒绝策略
- AbortPolicy() 线程池满了,还有人进来,不处理这个人的请求,同时抛出异常
- CallerRunsPolicy() 哪里来的请求,回到哪里去(请求对应的主方法)
- DiscardPolicy() 队列满了,丢掉后来的请求,不抛出异常
- DiscardOldestPolicy() 队列满了,尝试去和最早进行服务的窗口竞争,看那里的服务是否快要结束了,结束就进去提出请求,这种策略也不抛出异常
小结
1、线程池不允许使用Executor创建(不安全),而是通过ThreadPoolExecutor这样的方式
2、如何定义线程池最大的大小?
(1) CPU密集型
根据cpu核数来设定
Runtime.getRuntime().availableProcessors();
(2) IO密集型
判断程序中十分耗IO的线程,一般设置为其两倍的大小
评论 (0)