通过ThreadPoolExecutor 进行多线程编程
来源:互联网 发布:python sorted函数 编辑:程序博客网 时间:2024/04/28 02:14
最近搞了个项目,涉及到多线程编程,同时呢,有涉及线程需要返回结果的功能。
首先,介绍一下ThreadPoolExecutor
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
corePoolSize: 线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
keepAliveTime: 线程池维护线程所允许的空闲时间
unit: 线程池维护线程所允许的空闲时间的单位
workQueue: 线程池所使用的缓冲队列
handler: 线程池对拒绝任务的处理策略
handler有四个选择:
ThreadPoolExecutor.AbortPolicy()
抛出java.util.concurrent.RejectedExecutionException异常
ThreadPoolExecutor.CallerRunsPolicy()
重试添加当前的任务,他会自动重复调用execute()方法
ThreadPoolExecutor.DiscardOldestPolicy()
抛弃旧的任务
ThreadPoolExecutor.DiscardPolicy()
抛弃当前的任务
// 构造一个线程池
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),
new ThreadPoolExecutor.DiscardOldestPolicy());
在这段程序中,main()方法相当于一个残忍的领导,他派发出许多任务,丢给一个叫 threadPool的任劳任怨的小组来做。
这个小组里面队员至少有两个,如果他们两个忙不过来,任务就被放到任务列表里面。
如果积压的任务过多,多到任务列表都装不下(超过3个)的时候,就雇佣新的队员来帮忙。但是基于成本的考虑,不能雇佣太多的队员,至多只能雇佣 4个。
如果四个队员都在忙时,再有新的任务,这个小组就处理不了了,任务就会被通过一种策略来处理,我们的处理方式是不停的派发,直到接受这个任务为止(更残忍!呵呵)。
因为队员工作是需要成本的,如果工作很闲,闲到 3SECONDS都没有新的任务了,那么有的队员就会被解雇了,但是,为了小组的正常运转,即使工作再闲,小组的队员也不能少于两个。
以上是参考别人的博客,感觉写的真的不错,尤其是这个例子,通俗易懂。
下面是两种线程的需求:
1、线程需要有返回值
实现callable接口的 call方法
思路:
可以在call里写循环,创建线程类的时候用List、Map等集合来传参
classShortenUrlimplementsCallable<List<Map<String, String>>>{
@Override
publicList<Map<String, String>> call()throwsException {
returnbackList;
}
}
调用时:
private static final intsize=1000;
private final staticExecutorServicepool= ThreadPoolExecutorUtil.getInstance().getThreadPoolExecutorService();
CompletionService<List<Map<String, String>>> urlThreadService =
newExecutorCompletionService<>(pool);
使用这个urlThreadService 进行创建线程
urlThreadService.submit(
newShortenUrl(threadUrlRecordList, url_long_Map, url_key_Map,
thread_message_Map, messageMap_Map, batch_id));
使用这个方式判断线程是否执行完毕
for(inti =0; i< urlThreadCount; ++i){
try{
List<Map<String, String>> back = urlThreadService.take().get();
if(null!= back && back.size() >0){
fromUrlThreadList.addAll(back);
}
}catch(InterruptedException | ExecutionException e) {
logger.error("线程等待异常:{}", e);
}
}
2、线程不需要返回值
实现Runnable接口的 run方法
classMySendSmsThreadimplementsRunnable{
@Override
public voidrun(){
finally{
doneSignal.countDown();
}
}
}
finalCountDownLatch doneSignal =newCountDownLatch(threadCount);
try{
doneSignal.await();
logger.info("\n 线程执行完毕 jobSms:{}", jobSms.getId());
}catch(InterruptedException e) {
logger.error("线程等待异常:{}", e);
}
可以使用doneSignal 进行线程是否执行的判断
inttotal = sendDataMap.size();
intthreadCount = (int) (total / size+ ((total %size!=0) ?1:0));
使用这种办法设置线程数量
for(intj =0; j< threadCount; ++j){
intstartIndex = j *size;
inttoIndex = ((j +1) *size) > sendSmsList.size() ? sendSmsList.size() : (j + 1) *size;
List<NewSendSms> threadRecordList = sendSmsList.subList(startIndex, toIndex);
ThreadPoolExecutorUtil.getInstance().getThreadPoolExecutorService()
.execute(newGetStatusThread(batchNo, threadRecordList, doneSignal));
调用
}
使用这种办法获得每个线程中的List
这个LinkedBlockingQueue,有兴趣的话可以去查查为什么使用这个队列作为实现方式
public class ThreadPoolExecutorUtil { public static final int NTHREADS = 200;// 默认线程池个数 private ThreadPoolExecutorUtil() { } private volatile static ThreadPoolExecutorUtil INSTANCE; private static final LinkedBlockingQueue<Runnable> QUEUE = new LinkedBlockingQueue<>(5000);// 后续应加入队列长度监听机制 private ExecutorService executorService = new ThreadPoolExecutor(NTHREADS, NTHREADS, 0L, TimeUnit.MILLISECONDS, QUEUE); public static ThreadPoolExecutorUtil getInstance() { if (null == INSTANCE) { synchronized (ThreadPoolExecutorUtil.class) { if (null == INSTANCE) { INSTANCE = new ThreadPoolExecutorUtil(); } } } return INSTANCE; } public ExecutorService getThreadPoolExecutorService() { if (null == executorService) { ThreadPoolExecutor executor = new ThreadPoolExecutor(NTHREADS, NTHREADS, 0L, TimeUnit.MILLISECONDS, QUEUE); /** * 重写Rejected策略,缺省抛出TaskRejectedException异常,然后不执行 * 当pool已经达到maxsize的时候 不在新线程中执行任务,而是有调用者所在的线程来执行 */ executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor; } return executorService; } @PreDestroy public void destroy() { executorService.shutdown(); }}
刚刚接触,如有错误还请各位大牛指出
阅读全文
2 0
- 通过ThreadPoolExecutor 进行多线程编程
- Java多线程之ThreadPoolExecutor
- ThreadPoolExecutor 线程池 多线程
- Java多线程:ThreadPoolExecutor详解
- Android 多线程 ThreadPoolExecutor
- 多线程之ThreadPoolExecutor
- Java多线程:ThreadPoolExecutor详解
- Java多线程之ThreadPoolExecutor
- java多线程之ThreadPoolExecutor
- Java多线程:ThreadPoolExecutor详解
- java多线程之ThreadPoolExecutor
- 多线程ThreadPoolExecutor学习总结
- Java多线程--ThreadPoolExecutor
- 多线程之多线程ThreadPoolExecutor
- C#如何进行多线程编程
- QT:多线程及通过事件进行通信
- 多线程 通过管道进行线程间通信
- ThreadPoolExecutor并行编程Demo
- Android之视频裁剪
- 鸡国福利
- 如何解锁oracle数据库scott账户,windows平台
- 关于在Linux下上传代码至Github
- groovy中each迭代get方法获取值未空,原因探究。GStringImpl
- 通过ThreadPoolExecutor 进行多线程编程
- JAVA互联网架构学习之Mybatis
- 如何统计iOS产品不同渠道的下载量?
- 我的第一个 java 小程序 Hello World!
- Go入门(五)-函数
- 使用注解处理器跳过微信包名限制(三)
- intellij IDEA 中,.properties文件unicode转中文
- 数据卷容器
- LightOJ