20220816学习内容 二 线程池参数和方法

构造器中各个参数的含义:

 1.corePoolSize
线程池中的核心线程数。当提交一个任务时,线程池创建一个新线程执行任务,
直到当前线程数等于corePoolSize;如果当前线程数为corePoolSize,继续提
交的任务被保存到阻塞队列中,等待被执行。

2.maximumPoolSize
线程池中允许的最大线程数。如果当前阻塞队列满了,且继续提交任务,则创建
新的线程执行任务,前提是当前线程数小于maximumPoolSize。

3.keepAliveTime
线程空闲时的存活时间。默认情况下,只有当线程池中的线程数大于corePoolSize
时,keepAliveTime才会起作用,如果一个线程空闲的时间达到keepAliveTime,则
会终止,直到线程池中的线程数不超过corePoolSize。但是如果调用了
allowCoreThreadTimeOut(boolean)方法,keepAliveTime参数也会起作用,直到
线程池中的线程数为0。

4.unit
keepAliveTime参数的时间单位。
例如TimeUnit.DAYS

 5.workQueue
任务缓存队列,用来存放等待执行的任务。如果当前线程数为corePoolSize,继续提交的
任务就会被保存到任务缓存队列中,等待被执行。

一般来说,这里的BlockingQueue有以下三种选择:
- SynchronousQueue:一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态。因此,如果线程池中始终没有空闲线程(任务提交的平均速度快于被处理的速度),可能出现无限制的线程增长。
- LinkedBlockingQueue:基于链表结构的阻塞队列,如果不设置初始化容量,其容量
Integer.MAX_VALUE,即为无界队列。因此,如果线程池中线程数达到了corePoolSize,且始终没有空闲线程(任务提交的平均速度快于被处理的速度),任务缓存队列可能出现无限制的增长。
- ArrayBlockingQueue:基于数组结构的有界阻塞队列,按FIFO排序任务。

 6.threadFactory
线程工厂,创建新线程时使用的线程工厂。

 7.handler
任务拒绝策略,当阻塞队列满了,且线程池中的线程数达到maximumPoolSize,如果继续提交任务,就会采取任务拒绝策略处理该任务,线程池提供了4种任务拒绝策略:
- AbortPolicy:丢弃任务并抛出RejectedExecutionException异常,默认策略;
- CallerRunsPolicy:由调用execute方法的线程执行该任务;
- DiscardPolicy:丢弃任务,但是不抛出异常;
- DiscardOldestPolicy:丢弃阻塞队列最前面的任务,然后重新尝试执行任务(重复此过程)。
当然也可以根据应用场景实现RejectedExecutionHandler接口自定义饱和策略,如记录日志或持久
化存储不能处理的任务。
 

public class Test1 {
	public static void main(String[] args) {
//		ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 9, 16, TimeUnit.DAYS, new SynchronousQueue<>());
//		ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 9, 16, TimeUnit.DAYS, new ArrayBlockingQueue<>(2));
		ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 6, 1, TimeUnit.HOURS, new SynchronousQueue<>(),
				Executors.defaultThreadFactory(), new CallerRunsPolicy());
		for (int i = 0; i < 10; i++) {
			int kk = i;
			pool.submit(() -> {
				for (int k = 0; k < 5; k++) {
					System.err.println(Thread.currentThread() + "::" + kk);
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			});
		}
		pool.shutdown();
	}
}

  Executors创建线程池:


 * - newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,
 * 可灵活回收空闲线程,若无可回收重用时则新建线程
 * 
 * new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,
       new SynchronousQueue<Runnable>());

 * 用来创建一个可以无限扩大的线程池,适用于服务器负载较轻,执行很多短期异步
 * 任务
 * 
 *     Integer.MAX_VALUE--OOM
 * 
 * - newFixedThreadPool 创建一个固定大小的定长线程池,可控制线程最大并发数,
 * 超出的线程会在队列中等待
 * 
 * new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
                                      
 * 因为采用无界的阻塞队列,所以实际线程数量永远不会变化,适用于可以预测线程数量
 * 的业务中,或者服务器负载较重,对当前线程数量进行限制
 * 
 * - newScheduledThreadPool创建一个定长线程池,支持定时及周期性任务执行
 * 可以延时启动,定时启动的线程池,适用于需要多个后台线程执行周期任务的场景
 * public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService
 * 
 * super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue());
              
 * - newSingleThreadExecutor创建一个单线程化的线程池,它只会用唯一的工作线程
 * 来执行任务,保证所有任务按照指定顺序(FIFO先进先出, LIFO后进先出, 优先级)执行
 * 适用于需要保证顺序执行各个任务,并且在任意时间点,不会有多个线程是活动的场景 
 * 
 * - newWorkStealingPool:创建一个拥有多个任务队列的线程池,可以减少连接数
 *    创建当前可用cpu数量的线程来并行执行,适用于大耗时的操作,可以并行来执行

 ExecutorService提供提交任务的方式:

线程池框架提供了两种方式提交任务,submit()和execute(),

通过submit()方法提交的任务可以返回任务执行的结果,

通过execute()方法提交的任务不能获取任务执行的结果。 

public class Test4 {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		Future[] fs=new Future[10];
		ExecutorService es = Executors.newFixedThreadPool(3);
		
//		es.execute(null); 这里的参数为Runnable,所以不会有返回值
		
		for (int i = 1; i <= 10; i++) {
			int begin = (i - 1) * 100 + 1;
			int end = i * 100;
			fs[i-1]=es.submit(() -> {   //参数可以是Callable或者Runnable,如果Runnable则没有返回值,Callable则可以通过Future获取返回值
				int res = 0;
				for (int k = begin; k <= end; k++) {
					res += k;
				}
				return res;
			});
		}
		int res=0;
		for(Future<Integer> f:fs)
			res+=f.get();
		System.out.println(res);
	}
}

 ExecutorService的方法:关闭线程池
  shutdownNow:对正在执行的任务全部发出interrupt(),停止执行,对还未开始执
  行的任务全部取消,并且返回还没开始的任务列表
  shutdown:当调用shutdown后,线程池将不再接受新的任务,但也不会去强制终止
 已经提交或者正在执行中的任务

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值