ThreadPoolExecutor使用
来源:互联网 发布:矩阵归一化处理 编辑:程序博客网 时间:2024/05/17 12:04
ThreadPoolExecutor是 java提供的一个线程池工具类
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
maximumPoolSize 最大线程数
keepAliveTime 线程最大空闲时间 (当线程数大于 corePoolSize时,剩余的线程的空闲时间大于keepAliveTime将会被回收
unit keepAliveTime对应的时间单位
workQueue 任务队列
threadFactory 线程工厂
handler (饱和策略) 当线程数达到最大,且任务队列已满,就会调用 此handler的方法处理
默认情况下 不传入 threadFactory会提供一个默认的值,Executors.defaultThreadFactory()
不过默认的线程池名字是很揪心的,格式都是 pool-poolNumber-thread-threadNumber
所以要是创建了好几个线程池,名字基本就是pool-1-thread-1,pool-1-thread-2, pool-2-thread-1, pool-2-thread-2,完全没有可读性
DefaultThreadFactory() { SecurityManager s = System.getSecurityManager(); group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-"; }google 的guava提供了一个方法设置线程池名称 new ThreadFactoryBuilder().setNameFormat("scheduler-pool-%d").build();
这样一看就知道是什么线程了
如果不想引入google的guava,就自己写个类继承ThreadFactory,
public class MqThreadFactory implements ThreadFactory { private String poolName; private final ThreadGroup group; private final AtomicInteger threadNumber = new AtomicInteger(1); private final String namePrefix; public MqAppThreadFactory(String poolName) { SecurityManager s = System.getSecurityManager(); group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); namePrefix = poolName + "-pool" + "-thread-"; } public Thread newThread(Runnable r) { Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0); if (t.isDaemon()) t.setDaemon(false); if (t.getPriority() != Thread.NORM_PRIORITY) t.setPriority(Thread.NORM_PRIORITY); return t; }}调用的时候传入poolName就行了
java提供了几种饱和策略供选择
AbortPolicy 当线程数达到最大,且任务队列已满,直接抛出异常,这也是ThreadPoolExecutor的默认饱和策略
DiscardPolicy 直接丢弃任务
DiscardOldestPolicy 丢弃队列里最近的一个任务,并执行当前任务
CallerRunsPolicy 只用调用者所在线程来运行任务
threadPoolExecutor使用方式:
ExecutorService pool=new ThreadPoolExecutor(coreThreadSize, maxThreadSize,keepAliveTime, unit, queue, new MqThreadFactory(poolName)这里使用默认的饱和策略
然后提交任务到线程池就行了
executorService.execute(new QueueHandler());
当然也可以调用 executorservice.submit 方法
提交到线程池的任务并不一定会马上执行,之前碰到一个问题,线程的代码默认监听BlockingQueue,
希望提高性能,所以项目初始化的时候,循环调用execute方法,希望线程池中的所有线程默认都开启,
结果发现,线程数维持在,corePoolSize,
下面是execute方法的执行流程:
1、线程池判断核心线程池里的线程是否都在执行任务。如果不是,则创建一个新的工作
线程来执行任务。如果核心线程池里的线程都在执行任务,则进入下个流程。
2、线程池判断工作队列是否已经满。如果工作队列没有满,则将新提交的任务存储在这
个工作队列里。如果工作队列满了,则进入下个流程。
3、线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程
来执行任务。如果已经满了,则交给饱和策略来处理这个任务
具体的大家可以看看 java并发编程的艺术 这本书,个人觉得在某些细节上面讲的比 java并发编程实战要好
- ThreadPoolExecutor使用
- ThreadPoolExecutor使用
- ThreadPoolExecutor使用
- ThreadPoolExecutor使用
- ThreadPoolExecutor的使用
- ThreadPoolExecutor使用介绍
- Java ThreadPoolExecutor 使用
- ThreadPoolExecutor使用学习
- ThreadPoolExecutor使用介绍
- ThreadPoolExecutor使用介绍
- ThreadPoolExecutor使用介绍
- ThreadPoolExecutor使用介绍
- ThreadPoolExecutor使用例子
- 关于ThreadPoolExecutor使用介绍
- ThreadPoolExecutor使用介绍
- ThreadPoolExecutor使用介绍
- ThreadPoolExecutor使用介绍
- ThreadPoolExecutor使用介绍
- SIEM 与SOC
- S3C2440 -- 启动文件和Makefile文件分析
- POJ 3669 Meteor Shower
- Gradle解决依赖冲突
- 初识STM32固件库
- ThreadPoolExecutor使用
- 在Cocoapods上发布自己的代码
- ISP算法概述
- session和cookie的区别和联系
- Java实现MD5加密及解密的代码实例分享
- Linux格式化硬盘 常用命令小记
- STM32通过SPI采集DT50 ADS8320数据
- 假币问题 oj41
- Inorder Tree Traversal | Iterative & Recursive