多线程-线程池

java提供的线程池

1、ExecutorService exeThread = Executors.newCachedThreadPool(); // 核心线程数为空 最大线程数量没有上限,没有存储性质的阻塞队列,它的取值操作和放入操作必须是互斥的
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
2、ExecutorService exeThread2 = Executors.newFixedThreadPool(1); //核心线程数等于最大线程数,所有线程都是核心线程(非核心线程数 = 最大线程数 - 核心线程数),采用无参数的链表阻塞队列,最大的任务数可达232-1个。因此存在任务积压导致内存溢出的风险
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
3、ExecutorService exeThread3 = Executors.newSingleThreadExecutor();//只有一个核心线程,无限长的队列
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
}

推荐手动创建线程池ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize, //核心线程数
int maximumPoolSize, //最大线程数
long keepAliveTime, // 最大空闲时间
TimeUnit unit, //时间单位
BlockingQueue workQueue, // 阻塞队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler //拒绝策略
) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
prestartAllCoreThreads();
}

参数

1、int corePoolSize 核心线程数
线程池维护的最小线程数量,核心线程创建后不会被回收(注意:设置allowCoreThreadTimeout=true后,空闲的核心线程超过存活时间也会被回收)。
大于核心线程数的线程,在空闲时间超过keepAliveTime后会被回收。
线程池刚创建时,里面没有一个线程,当调用 execute() 方法添加一个任务时,如果正在运行的线程数量小于corePoolSize,则马上创建新线程并运行这个任务。
2、int maximumPoolSize最大线程数注:(非核心线程数 = 最大线程数 - 核心线程数)
线程池允许创建的最大线程数量。
当添加一个任务时,核心线程数已满、阻塞已满、最大线程数还未到最大,并且没有空闲线程,会创建一个新线程,然后从工作队列的头部取出一个任务交由新线程来处理,而将刚提交的任务放入工作队列尾部。
3、long keepAliveTime最大空闲时间
当一个可被回收的线程的空闲时间大于keepAliveTime,就会被回收
设置allowCoreThreadTimeout=true后,空闲的核心线程超过存活时间也会被回收
4、TimeUnit unit时间单位
TimeUnit.NANOSECONDS
TimeUnit.MICROSECONDS
TimeUnit.MILLISECONDS // 毫秒
TimeUnit.SECONDS //秒
TimeUnit.MINUTES //分
TimeUnit.HOURS //时
TimeUnit.DAYS //天
5、BlockingQueue workQueue 阻塞队列
常用的阻塞队列表格

workQueue描述
ArrayBlockingQueue数组型阻塞队列:数组结构,初始化时传入大小,有界,FIFO,使用一个重入锁,默认使用非公平锁,入队和出队共用一个锁,互斥;
LinkedBlockingQueue链表型阻塞队列:链表结构,默认初始化大小为Integer.MAX_VALUE,有界(近似无解),FIFO,使用两个重入锁分别控制元素的入队和出队,用Condition进行线程间的唤醒和等待;
SynchronousQueue同步队列:容量为0,添加任务必须等待取出任务,这个队列相当于通道,不存储元素;
PriorityBlockingQueue优先阻塞队列:无界,默认采用元素自然顺序升序排列;
DelayQueue延时队列:无界,元素有过期时间,过期的元素才能被取出;

6、ThreadFactory threadFactory,线程工厂

7、RejectedExecutionHandler handler 拒绝策略

策略描述
AbortPolicy该策略是线程池的默认策略。使用该策略时,如果线程池队列满了丢掉这个任务并且抛出RejectedExecutionException异常
DiscardPolicy这个策略和AbortPolicy的slient版本,如果线程池队列满了,会直接丢掉这个任务并且不会有任何异常
DiscardOldestPolicy这个策略从字面上也很好理解,丢弃最老的。也就是说如果队列满了,会将最早进入队列的任务删掉腾出空间,再尝试加入队列
CallerRunsPolicy使用此策略,如果添加到线程池失败,那么主线程会自己去执行该任务,不会等待线程池中的线程去执行。
自定义如果以上策略都不符合业务场景,那么可以自己定义一个拒绝策略,只要实现RejectedExecutionHandler接口,并且实现rejectedExecution方法就可以了

线程池执行流程

在这里插入图片描述

线程池运行

线程池运行有两种提交方式
1、execute()方法
execute()方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功
2、submit()方法
submit()方法用于提交需要返回值的任务。线程池会返回一个future类型的对象,通过这个future对象可以判断任务是否执行成功,并且通过futrue的get() 方法来获取返回值,get() 方法会阻塞当前线程直到任务完成,而使用get(long timeout,TimeUnit unit)方法则会阻塞当前线 程一段时间后立即返回,这时候有可能任务没有执行完。

线程池关闭

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值