java中创建线程池有两种方式
1.通过提供的工具类Executors进行创建。
但是不推荐这样创建,通过源码可以看到,它创建出来的四个线程池都存在问题。
Executors 返回线程池对象的弊端如下:
FixedThreadPool 和 SingleThreadExecutor : 允许请求的队列长度为Integer.MAX_VALUE ,可能堆积大量的请求,从而导致 OOM。
CachedThreadPool 和 ScheduledThreadPool : 允许创建的最大线程数量为 Integer.MAX_VALUE ,可能会创建大量线程,从而导致 OOM。
2.通过ThreadPoolExecutors自己创建
上面的工具类也是这样创建的。
ExecutorService executorService = new ThreadPoolExecutor(
2,//核心线程数量
5,//最大线程数量
30,//超过核心线程数的线程空闲时的存活时间
TimeUnit.SECONDS,//时间的单位
new LinkedBlockingDeque<Runnable>(3),//等待队列
Executors.defaultThreadFactory(),//创建线程时需要的,默认就好
/*
CallerRunsPolicy:调用者模式,当线程超过线程所能容纳的最大线程时,把多余的线程回退给调用者
这里是回退给main。
AbortPolicy:终止模式,直接报异常。
DiscardOldestPolicy:丢弃最老的一个不报异常。
DiscardPolicy:丢弃
*/
new ThreadPoolExecutor.DiscardPolicy());//拒绝策略
try {
for (int i = 0; i < 10; i++) {
executorService.execute(()->{
System.out.println(Thread.currentThread().getName()+"办理业务");
});
}
}finally {
executorService.shutdown();
Object o = new Object();
}
线程进入线程池的流程:
当扩容来的线程无事做操作最大存活时间,就会停掉,回退到核心线程的数量。