Executors和ThreadPoolExecutor线程池

问题来源:阿里巴巴开发手册并发编程这块写有一条:线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式创建.

线程池的优点:
减少内存资源的消耗.
提高请求处理速度
避免出现OOM

Executors创建线程的方式有三种.只讨论下面这种:
Executors创建 ThreadPoolExecutor对象的方法有三个:

Executors.newCachedThreadPool (创建可缓存的线程池)
Executors.newSingleThreadExecutor (创建单线程的线程池)
Executors.newFixedThreadPool(创建固定长度的线程池)
在这里插入图片描述

ThreadPoolExecutor构造函数有四个最终调用的都是一个:

//手动创建一个线程池
ThreadPoolExecutor thread1 = 
                 new ThreadPoolExecutor(corePoolSize, //核心线程数
										maximumPoolSize, //最大池的大小
										keepAliveTime, //空闲线程保持时间
										unit,      //时间单位
										workQueue,//阻塞队列							
										handler); //拒绝服务助手  回调函数,给出提示信息

ThreadPoolExecutor threadPool=
				new ThreadPoolExecutor(5, //核心线程数
				                       10, //最大池的大小
									   30L,//空闲线程保持时间30
									   TimeUnit.SECONDS,//时间单位秒
						new ArrayBlockingQueue(5),//阻塞线程
						new RejectedExecutionHandler() {//拒绝服务助手  回调函数,给出提示信息,多态,内部类,回调函数 
					
					@Override
					public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
						System.out.println("线程数超过了线程池的容量,拒绝执行任务-->"+r);
						
					}
				});

手动创建一个线程池,用到的是ThreadPoolExecutor类的六个参数的构造方法
以上面的方法为例:
我们是设置核心线程池数5个,最大线程池10个,线程空闲时间30秒,长度为5的阻塞队列,和拒绝服务助手运行时
运行时,首先用核心线程池来调度线程有新的任务,先用核心线程来处理.
第一种情况,核心线程数没有达到5个,那么有任务进来就会创建新的线程,直到有5个核心线程
第二种情况,已经有5个核心线程,这时候有任务来,先看有没有空闲的核心线程,有的话就用核心线程,没有就把它放进队列中
等待有空闲的核心线程,再把任务从队列中take出来,给空闲核心线程
在队列中,队列为空和队列满都是阻塞状态
第三种情况,核心线程已经满了,队列中也满了,就会创建临时线程,来处理任务,运行一段时间后,
这时候如果有核心线程或是临时线程空闲,线程池就会对这些线程,看其是否达到了线程空闲时间
达到了线程空闲时间的线程,就会被销毁,他会把没执行完的临时线程变为核心线程,
执行完的核心线程和临时线程被销毁,为了保持核心线程数是5
第四种情况,核心线程已经满了,队列中也满了,临时线程也满了,就会调用拒绝服务助手,提示报错.

注意:
ThreadPoolExecutor 会根据核心线程池数和最大大小,来自动调整
当我们用execute(Runnable)提交任务小于核心线程数时就是第一种情况,优先创建新线程直到等于核心线程数
当我们核心线程没有空闲,队列也满了,这时就会创建临时线程,但临时线程数+核心线程数不能超过最大大小
如果核心线程数和最大大小设置相等,则是创建了固定大小的线程池,
如果最大大小设置特别大(像Integer.MAX_VALUE),这表示没有上限,(但也要根据CPU,很为这很吃CPU)
一般时候,我们根据构造来设置核心线程池和最大大小,但也可以调用方法来设置.

Executors.newCachedThreadPool (创建可缓存的线程池)

其中的核心线程数为0 ,队列是一个不存储元素的队列,
因为Integer.MAX_VALUE非常大,所以,就会无限创建非核心线程,
造成OOM.

Executors.newSingleThreadExecutor (创建单线程的线程池)

这个会创建一个核心线程,然后其他的放到队列中,
LinkedBlockingQueue队列的大小是Integer.MAX_VALUE非常大.就可以往里面无限放任务,
所以在资源有限的情况下,也容易造成OOM.

Executors.newFixedThreadPool(创建固定长度的线程池)

和上面的类似LinkedBlockingQueue队列非常大,容易造成OOM
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值