本文主要是介绍线程池newCachedThreadPool,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1.查看newCachedThreadPool线程池创建方法
创建线程池:
Executor cachedThread = Executors.newFixedThreadPool(1);
查看底层实现:
public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
}
通过源码得出newCachedThreadPool的初始核心数是0最大核心数是使用的是 Integer.MAX_VALUE,SynchronousQueue是为队列。
2.使用ThreadPoolExecutor模拟newCachedThreadPool
public static void main(String[] args) {int corePoolSize = 0;int maximumPoolSize = Integer.MAX_VALUE;long keepAliveTime = 60L;SynchronousQueue syncQueue = new SynchronousQueue<Runnable>();Executor cachedThread = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime, TimeUnit.SECONDS,syncQueue);for (int i = 0; i < 50000; i++) {cachedThread.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}});}}
3.执行查询系统资源占用情况
从图中可以看出CPU占用非常厉害,可能会导致机器卡死。
将程序改一下:
运行得出的参数:
可以看到workQueue的值一直是0,跑了10次worker数据为10
4、修改maximumPoolSize参数值为5
现执行程序
for (int i = 0; i < 50000; i++) {cachedThread.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}});}
执行结果:
从图中结果可以看出再执行到第5的时候就出现异常了。
再修改程序:每执行5个线程睡眠0.1秒
for (int i = 0; i < 50000; i++) {//每执行5个线程睡眠0.1秒if(i%5 == 0){try {System.out.println("睡眠i==" +i);Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}cachedThread.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}});}
执行结果:顺利完成且没有任何异常
5.结论
1.newCachedThreadPool最大的核心是int的最大值,如果有业务会在核心数内一直创建线程,导致CPU占用非常的高。
2.SynchronousQueue在此仅用于阻塞,不会进行何的缓存。
3.当创建的线程在业务未完成前,如果已达到最大核心数则不能再创建线程,如果再继续创建则会抛出异常。当可能worker有空的时候可以再次执行业为。可以看出有点像生产者消费模式,如果消费不及时者会不再继续生产,如果继续生产会导致失败。
这篇关于线程池newCachedThreadPool的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!