线程池及优缺点
线程池的出现是为了提高资源的利用率。对于任何语言的程序来说都是运行内存里的。频繁的关闭,创建线程非常耗费资源,线程池的核心是采用资源使用后不关闭的机制,将用完的线程回收到池子里。即解决了创建又解决了关闭。至于其他好处都是由这个核心机制扩展的,缺点就是提前占用了系统资源。
三大方法
面试时面试官通常会问创建线程池有几种方式,我在面试蚂蚁的时候被问到过,以下是JDK默认的3种。这些方式是不建议用的,如果安装了阿里代码开发的规范,Executors就会爆红。
public class ThreeMethod {
public static void main(String[] args) {
threeParam();
}
public static void threeParam() {
// 只有一个线程的线程池
ExecutorService executorService = Executors.newSingleThreadExecutor();
// 固定线程数量的线程池
ExecutorService executorService1 = Executors.newFixedThreadPool(5);
// 可根据实际情况伸缩的线程池
ExecutorService executorService2 = Executors.newCachedThreadPool();
// 线程池使用完需要关闭线程池
try {
for (int i = 0; i < 10; i++) {
executorService2.execute(() -> {
System.out.println("当前线程=>" + Thread.currentThread().getName());
});
}
} finally {
executorService2.shutdown();
}
}
}
七大参数
建议使用以下方式指定参数创建线程池。
public class SevenParam {
public static void main(String[] args) {
sevenParam();
}
public static void sevenParam() {
ExecutorService executor = new ThreadPoolExecutor(
2, // 核心线程池大小
5, // 最大核心线程池大小
3, // 超时了没有人调用就会释放
TimeUnit.SECONDS,// 超时单位
new LinkedBlockingDeque<>(3),// 阻塞队列
Executors.defaultThreadFactory(),// 创建线程工厂
new ThreadPoolExecutor.AbortPolicy());// 拒绝策略
try {
for (int i = 1; i <= 100; i++) {
executor.execute(()->{
System.out.println("获得线程池中的线程=》" + Thread.currentThread().getName());
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
四大拒绝策略
- AbortPolicy:银行满了,还有人进来,不处理这个人的,并抛出异常。超出最大承载,就会抛出异常:队列容量大小+maxPoolSize
- CallerRunsPolicy:哪来的去哪里 main线程进行处理
- DiscardPolicy: 队列满了,丢掉异常,不会抛出异常。
- DiscardOldestPolicy:队列满了,尝试去和最早的进程竞争,不会抛出异常
记忆技巧
记忆时记3个数字即可。
3(3大方法)
7(7大参数)
4(4大拒绝策略)