上篇写到了ThreadPoolExecutor构造方法前4个参数int corePoolSize、int maximumPoolSize,、long keepAliveTime、TimeUnit unit与工作流程机制,现在来看看后3个参数BlockingQueue workQueue、ThreadFactory threadFactory、RejectedExecutionHandler handler的含义与用法。

参数详解

workQueue:阻塞任务队列,用于保存任务以及为工作线程提供待执行的任务

block queue有以下几种实现:

  • ArrayBlockingQueue : 有界的数组队列
  • LinkedBlockingQueue : 可支持有界/无界的队列,使用链表实现
  • PriorityBlockingQueue : 优先队列,可以针对任务排序
  • SynchronousQueue : 队列长度为1的队列,和Array有点区别就是:client thread提交到block queue会是一个阻塞过程,直到有一个worker thread连接上来poll task。

    threadFactory:线程工厂,线程生成器

    handler:当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理;ThreadPoolExecutor内部有实现4个拒绝策略,默认为AbortPolicy策略:
  • CallerRunsPolicy:由调用execute方法提交任务的线程来执行这个任务
  • AbortPolicy:抛出异常RejectedExecutionException拒绝提交任务
  • DiscardPolicy:直接抛弃任务,不做任何处理
  • DiscardOldestPolicy:去除任务队列中的第一个任务,重新提交。

首先若正在运行的线程数量大于或等于 maximumPoolSize时:

public static void main(String[] args) {
ExecutorService executor = new ThreadPoolExecutor(2, 3, 1, TimeUnit.HOURS,
new LinkedBlockingQueue<>(1)); List<Future<String>> resultList = new ArrayList<Future<String>>();
for (int i = 0; i < 10 ; i++) {
Future<String> future = executor.submit(new MyWorker(i));
resultList.add(future);
} System.out.println("所有线程已经运行完成");
for (Future<String> future:resultList) {
try { System.out.println(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} } static class MyWorker implements Callable<String> {
private int i;
public MyWorker(int i) {
this.i = i;
} @Override
public String call() {
try {
System.out.println(i);
//模拟执行
Thread.sleep(500);
String result = "序号" + i+ "_当前线程==" + Thread.currentThread().getName();
return result;
} catch (Exception e) {
e.printStackTrace();
} return "error";
}
}

对此种情况进行处理,自定义拒绝处理类,实现RejectedExecutionHandler接口(和new ThreadPoolExecutor.CallerRunsPolicy()功能一致)

ExecutorService executor = new ThreadPoolExecutor(2, 3, 1, TimeUnit.HOURS,
new LinkedBlockingQueue<>(1), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return null;
}
}, new MyRejectedExecutionHandler()); static class MyRejectedExecutionHandler implements RejectedExecutionHandler { @Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
if (!executor.isShutdown()) {
r.run();
}
}
}

新增ThreadFactory自定义类:

static class MyThreadFactory implements ThreadFactory {

        private final AtomicInteger mThreadNum = new AtomicInteger(1);

        @Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "my-thread-" + mThreadNum.getAndIncrement());
System.out.println(t.getName() + " has been created");
return t;
}
}

ThreadPoolExecutor(下篇)的更多相关文章

  1. 系统间通信(5)——IO通信模型和JAVA实践 下篇

    7.异步IO 上面两篇文章中,我们分别讲解了阻塞式同步IO.非阻塞式同步IO.多路复用IO 这三种IO模型,以及JAVA对于这三种IO模型的支持.重点说明了IO模型是由操作系统提供支持,且这三种IO模 ...

  2. Asp.Net WebApi核心对象解析(下篇)

    在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...

  3. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  4. Android线程管理之ThreadPoolExecutor自定义线程池

    前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...

  5. 并发包的线程池第一篇--ThreadPoolExecutor执行逻辑

    学习这个很长时间了一直没有去做个总结,现在大致总结一下并发包的线程池. 首先,任何代码都是解决问题的,线程池解决什么问题? 如果我们不用线程池,每次需要跑一个线程的时候自己new一个,会导致几个问题: ...

  6. ThreadPoolExecutor源码学习(1)-- 主要思路

    ThreadPoolExecutor是JDK自带的并发包对于线程池的实现,从JDK1.5开始,直至我所阅读的1.6与1.7的并发包代码,从代码注释上看,均出自Doug Lea之手,从代码上看JDK1. ...

  7. ThreadPoolExecutor源码学习(2)-- 在thrift中的应用

    thrift作为一个从底到上除去业务逻辑代码,可以生成多种语言客户端以及服务器代码,涵盖了网络,IO,进程,线程管理的框架,着实庞大,不过它层次清晰,4层每层解决不同的问题,可以按需取用,相当方便. ...

  8. LabVIEW 吸星大法 - 看见的好东西都是我的(下篇)

    前言 写了多年的LabVIEW程序,你是否面临这样的问题 总是在做一些重复的工作,感觉很没有意思: 总在不停的写代码,做类似的控件,实现相同的功能,丝毫没有成就感: 总在天加班,没有时间去提高自己; ...

  9. TaintDroid剖析之DVM变量级污点跟踪(下篇)

    TaintDroid剖析之DVM变量级污点跟踪(下篇)作者:简行.走位@阿里聚安全 ​ 1 回顾 在上一章节中我们详细分析了TaintDroid对DVM方法参数和方法变量的变量级污点跟踪机制,现在我们 ...

随机推荐

  1. 【转】VS2010不能引用System.Data.OracleClient解决方法

    源地址:http://blog.csdn.net/iloli/article/details/8484674

  2. 【ARC075F】Mirrored 搜索/数位dp

    Description ​ 给定正整数DD,求有多少个正整数NN,满足rev(N)=N+Drev(N)=N+D,其中rev(N)rev(N)表示将NN的十进制表示翻转来读得到的数 Input ​ 一个 ...

  3. 【Thread】线程工厂-ThreadFactory

    ThreadFactory---线程工厂 在apollo源码中有这么一段代码 ExecutorService m_longPollingService = Executors.newSingleThr ...

  4. opencv学习笔记(五)----图像的形态学操作

    图像的形态学操作有基本的腐蚀和膨胀操作和其余扩展形态学变换操作(高级操作)-----开运算,闭运算,礼帽(顶帽)操作,黑帽操作...(主要也是为了去噪声,改善图像) 形态学操作都是用于处理二值图像(其 ...

  5. shell-006:检测80端口的存活情况

    注意细节问题,如下图所示 #!/bin/bash # 检测80端口是否存在 while : do n=`netstat -lnpt |grep ':80 ' |wc -l` if [ $n -eq ] ...

  6. docker记录

    # docker run 运行程序 # docker stop (docker kill) 终止容器. (首先应该执行 docker stop!!) #停止所有容器 docker stop $(doc ...

  7. mfix添加文件后重新生成configure文件

    mfix给了一些程序接口,大部分时候只用修改现有程序即可满足要求,这种情况不用修改configure文件,但是如果添加了新文件就需要做一些修改. 我用了Jian Cai的程序尝试了一下编译,该学者在2 ...

  8. ZOJ Monthly, January 2019 Little Sub and his Geometry Problem ZOJ4082(模拟 乱搞)

    在一次被自己秀死... 飞机 题目: 给出N,K, Q; 给出一个N*N的矩阵  , 与K个特殊点 , 与Q次查询 , 每次查询给出一个C , 问 在这个N*N矩阵中 , 有多少的点是满足这样的一个关 ...

  9. GDCM

    gdcmconv: gdcm 2.2.4 $Date$ Usage: gdcmconv [OPTION] input.dcm   output.dcm Convert a DICOM file int ...

  10. FFMpeg 版本错误

    错误情况: relocation error: /usr/local/lib/libavfilter.so.3: symbol sws_get_class, version LIBSWSCALE_2 ...