深入学习java源码之Executors.newFixedThreadPool()与Executors.newCachedThreadPool()

​Executor​​框架是指java5中引入的一系列并发库中与executor相关的一些功能类,其中包括线程池,Executor,Executors,ExecutorService,CompletionService,Future,Callable等。他们的关系为:

深入学习java源码之Executors.newFixedThreadPool()与Executors.newCachedThreadPool()_线程池

并发编程的一种编程方式是把任务拆分为一些列的小任务,即Runnable,然后在提交给一个Executor执行,Executor.execute(Runnalbe)。Executor在执行时使用内部的线程池完成操作。

Executor:一个接口,其定义了一个接收Runnable对象的方法executor,其方法签名为executor(Runnable command),

ExecutorService:是一个比Executor使用更广泛的子类接口,其提供了生命周期管理的方法,以及可跟踪一个或多个异步任务执行状况返回Future的方法

AbstractExecutorService:ExecutorService执行方法的默认实现

ScheduledExecutorService:一个可定时调度任务的接口

ScheduledThreadPoolExecutor:ScheduledExecutorService的实现,一个可定时调度任务的线程池

ThreadPoolExecutor:线程池,可以通过调用Executors以下静态工厂方法来创建线程池并返回一个ExecutorService对象:

整体关系如下图:

深入学习java源码之Executors.newFixedThreadPool()与Executors.newCachedThreadPool()_线程池_02

​java.util.concurrent.ThreadPoolExecutor​​ 类是线程池中最核心的类之一,因此如果要透彻地了解Java中的线程池,必须先了解这个类。

public class ThreadPoolExecutor extends AbstractExecutorService {
.....
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
//代码省略
}
...
}

ThreadPoolExecutor构造函数的各个参数说明

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

corePoolSize:核心池的大小。

核心池中的线程会一致保存在线程池中(即使线程空闲),除非调用allowCoreThreadTimeOut方法允许核心线程在空闲后一定时间内销毁,该时间由构造方法中的keepAliveTime和unit参数指定;
在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从这两个方法的名字就可以看出,是**“预创建线程”**的意思,即在没有任务到来之前就创建corePoolSize个线程(prestartAllCoreThreads)或者一个线程(prestartCoreThread);
maximumPoolSize:线程池允许的最大线程数。这个参数也是一个非常重要的参数,它表示在线程池中最多能创建多少个线程。

默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把新加入的任务放到缓存队列当中,缓存队列由构造方法中的workQueue参数指定,如果入队失败(队列已满)则尝试创建临时线程,但临时线程和核心线程的总数不能超过maximumPoolSize,当线程总数达到maximumPoolSize后会拒绝新任务;所以有两种方式可以让任务绝不被拒绝:

① 将maximumPoolSize设置为Integer.MAX_VALUE(线程数不可能达到这个值),CachedThreadPool就是这么做的;

② 使用无限容量的阻塞队列(比如LinkedBlockingQueue),所有处理不过来的任务全部排队去,FixedThreadPool就是这么做的。

keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。

默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用——当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会被销毁,直到线程池中的线程数不超过corePoolSize。但是如果调用了allowCoreThreadTimeOut(true)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;
unit:参数keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性:

TimeUnit.DAYS;              //天
TimeUnit.HOURS; //小时
TimeUnit.MINUTES; //分钟
TimeUnit.SECONDS; //秒
TimeUnit.MILLISECONDS; //毫秒
TimeUnit.MICROSECONDS; //微妙
TimeUnit.NANOSECONDS; //纳秒

并发库中所有时间表示方法都是以​​TimeUnit​​枚举类作为单位

workQueue:一个阻塞队列(BlockingQueue接口的实现类),用来存储等待执行的任务,一般来说,这里的阻塞队列有以下几种选择:

ArrayBlockingQueue    // 数组实现的阻塞队列,数组不支持自动扩容。所以当阻塞队列已满
// 线程池会根据handler参数中指定的拒绝任务的策略决定如何处理后面加入的任务

LinkedBlockingQueue // 链表实现的阻塞队列,默认容量Integer.MAX_VALUE(不限容),
// 当然也可以通过构造方法限制容量

SynchronousQueue // 零容量的同步阻塞队列,添加任务直到有线程接受该任务才返回
// 用于实现生产者与消费者的同步,所以被叫做同步队列

PriorityBlockingQueue // 二叉堆实现的优先级阻塞队列

DelayQueue // 延时阻塞队列,该队列中的元素需要实现Delayed接口
// 底层使用PriorityQueue的二叉堆对Delayed元素排序
// ScheduledThreadPoolExecutor底层就用了DelayQueue的变体"DelayWorkQueue"
// 队列中所有的任务都会封装成ScheduledFutureTask对象(该类已实现Delayed接口)

threadFactory:线程工厂,主要用来创建线程;默认情况都会使用Executors工具类中定义的默认工厂类DefaultThreadFactory。可以实现ThreadFactory接口来自己控制创建线程池的过程(比如设置创建线程的名字、优先级或者是否为Deamon守护线程)

handler:表示当拒绝处理任务时的策略,有以下四种取值(默认为AbortPolicy):

ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

可通过实现RejectedExecutionHandler接口来自定义任务拒绝后的处理策略

线程池状态转换

深入学习java源码之Executors.newFixedThreadPool()与Executors.newCachedThreadPool()_线程池_03

其中三个高字节位存储了线程池当前的运行状态,线程池状态有以下几个:

// runState is stored in the high-order bits
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;

RUNNING:接受新任务并处理队列中的任务
SHUTDOWN:不接受新任务但处理队列中的任务
STOP:不接受新任务也不处理队列中的任务并终断正在处理中的任务
TIDYING:所有任务已经终止,workerCount等于0,线程池切换到TIDYING后将会执行terminated()钩子方法
TERMINATED:terminated()方法已执行完成

整个过程的状态转换图如下:

深入学习java源码之Executors.newFixedThreadPool()与Executors.newCachedThreadPool()_阻塞队列_04

任务提交主要有三种方式:

execute(Runnable command):定义在Executor接口中
submit的三个重载方法:定义在ExecutorService接口中
invoke(invokeAll,invokeAny)提交方式:定义在ExecutorService接口中

submit最终都会调用execute方法去执行任务,区别在于submit方法返回一个FutureTask对象(​​顾名思义​​FutrueTask就是未来将执行的任务,可以通过FutureTask对象获取任务执行的结果)。

 

Executor

通过Executor来设计应用程序可以简化开发过程,提高开发效率,并有助于实现并发,在开发中如果需要创建线程可优先考虑使用Executor

使用Executors工具类创建线程池

Executors是线程池框架提供给我们的创建线程池的工具类,它里面提供了以下创建几类线程池的方法。

// 创建固定线程数量的线程池
public static ExecutorService newFixedThreadPool();
// 创建单个线程的线程池(本质上就是容量为1的FixedThreadPool)
public static ExecutorService newSingleThreadExecutor();
// 创建无数量限制可自动增减线程的线程池
public static ExecutorService newCachedThreadPool();

// 创建(可计划的)任务延时执行线程池
public static ScheduledExecutorService newScheduledThreadPool();
// 单线程版的任务计划执行的线程池
public static ScheduledExecutorService newSingleThreadScheduledExecutor();

Executors提供了一系列静态工厂方法用于创建各种线程池,返回的线程池都实现了ExecutorService接口。

前三个方法new了​​ThreadPoolExecutor​​​对象,而后面两个方法new了​​ScheduledThreadPoolExecutor​​对象。

public static ExecutorService newFixedThreadPool(int nThreads)

创建固定数目线程的线程池

newFixedThreadPool:创建可重用且固定线程数的线程池,如果线程池中的所有线程都处于活动状态,此时再提交任务就在队列中等待,直到有可用线程;如果线程池中的某个线程由于异常而结束时,线程池就会再补充一条新线程。

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
//使用一个基于FIFO排序的阻塞队列,在所有corePoolSize线程都忙时新任务将在队列中等待
new LinkedBlockingQueue<Runnable>());
}

 public static ExecutorService newSingleThreadExecutor()

创建一个单线程化的Executor

 newSingleThreadExecutor:创建一个单线程的Executor,如果该线程因为异常而结束就新建一条线程来继续执行后续的任务

public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
//corePoolSize和maximumPoolSize都等于,表示固定线程池大小为1
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。

newScheduledThreadPool:创建一个可延迟执行或定期执行的线程池

深入学习java源码之Executors.newFixedThreadPool()与Executors.newCachedThreadPool()_线程池_05

Executor executor = Executors.newFixedThreadPool(10);  
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("task over");
}
};
executor.execute(task);

executor = Executors.newScheduledThreadPool(10);
ScheduledExecutorService scheduler = (ScheduledExecutorService) executor;
scheduler.scheduleAtFixedRate(task, 10, 10, TimeUnit.SECONDS);

使用newScheduledThreadPool来模拟心跳机制

public class HeartBeat {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
Runnable task = new Runnable() {
public void run() {
System.out.println("HeartBeat.........................");
}
};
executor.scheduleAtFixedRate(task,5,3, TimeUnit.SECONDS); //5秒后第一次执行,之后每隔3秒执行一次
}
}

输出:

HeartBeat....................... //5秒后第一次输出
HeartBeat....................... //每隔3秒输出一个

public static ExecutorService newCachedThreadPool()

创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)

newCachedThreadPool:创建可缓存的线程池,如果线程池中的线程在60秒未被使用就将被移除,在执行新的任务时,当线程池中有之前创建的可用线程就重用可用线程,否则就新建一条线程

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
//使用同步队列,将任务直接提交给线程
new SynchronousQueue<Runnable>());
}
public class ThreadPoolTest {
public static void main(String[] args) throws InterruptedException {
ExecutorService threadPool = Executors.newCachedThreadPool();//线程池里面的线程数会动态变化,并可在线程线被移除前重用
for (int i = 1; i <= 3; i ++) {
final int task = i; //10个任务
//TimeUnit.SECONDS.sleep(1);
threadPool.execute(new Runnable() { //接受一个Runnable实例
public void run() {
System.out.println("线程名字: " + Thread.currentThread().getName() + " 任务名为: "+task);
}
});
}
}
}

输出:(为每个任务新建一条线程,共创建了3条线程)

线程名字: pool-1-thread-1 任务名为: 1
线程名字: pool-1-thread-2 任务名为: 2
线程名字: pool-1-thread-3 任务名为: 3

去掉第6行的注释其输出如下:(始终重复利用一条线程,因为newCachedThreadPool能重用可用线程)

线程名字: pool-1-thread-1 任务名为: 1
线程名字: pool-1-thread-1 任务名为: 2
线程名字: pool-1-thread-1 任务名为: 3

通过使用Executor可以很轻易的实现各种调优 管理 监视 记录日志和错误报告等待。

 

Executor的生命周期

ExecutorService提供了管理Eecutor生命周期的方法,ExecutorService的生命周期包括了:运行 关闭和终止三种状态。

ExecutorService在初始化创建时处于运行状态。

shutdown方法等待提交的任务执行完成并不再接受新任务,在完成全部提交的任务后关闭

shutdownNow方法将强制终止所有运行中的任务并不再允许提交新任务

当调用ExecutorService.shutdown()后,处于关闭状态,isShutdown()方法返回true。这时,不应该再想Executor中添加任务,所有已添加的任务执行完毕后,Executor处于终止状态,isTerminated()返回true。

如果Executor处于关闭状态,往Executor提交任务会抛出unchecked exception RejectedExecutionException。

ExecutorService executorService = (ExecutorService) executor;  
while (!executorService.isShutdown()) {
try {
executorService.execute(task);
} catch (RejectedExecutionException ignored) {

}
}
executorService.shutdown();

可以将一个Runnable或Callable提交给ExecutorService的submit方法执行,最终返回一上Futire用来获得任务的执行结果或取消任务

(任务执行完成后并返回执行结果)

public class CallableAndFuture {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Callable<String>() { //接受一上callable实例
public String call() throws Exception {
return "MOBIN";
}
});
System.out.println("任务的执行结果:"+future.get());
}
}

输出:

任务的执行结果:MOBIN

FutrueTask

FutureTask实现Future接口,Future接口及其相关类继承图如下:

深入学习java源码之Executors.newFixedThreadPool()与Executors.newCachedThreadPool()_创建线程_06

 

FutureTask类中定义了如下的状态:

private volatile int state;
private static final int NEW = 0;// 任务已被创建(new的时候默认状态为0)
private static final int COMPLETING = 1;// 任务即将完成(已获取返回值或已捕获异常)
private static final int NORMAL = 2;// 任务正常完成(以返回值的形式完成任务)
private static final int EXCEPTIONAL = 3;// 任务异常完成(任务执行过程发生异常并被捕获)
private static final int CANCELLED = 4;// 任务已被取消(任务还没被执行就被取消了,可能在排队)
private static final int INTERRUPTING = 5;// 任务正在中断(任务执行时被取消)
private static final int INTERRUPTED = 6;// 任务已经中断(INTERRUPTING的下一个状态)

FutureTask的状态转换图如下(其中绿色标注的是外部可调用的方法,其他方法均有内部调用,RUNNING状态是我附加的状态,表示该任务已经被运行):

深入学习java源码之Executors.newFixedThreadPool()与Executors.newCachedThreadPool()_创建线程_07

更多种类的线程池MoreExecutors
Guava是Google提供的一个最受欢迎的通用工具包。它提供了很多并发工具,其中包括几个便捷的ExecutorService实现类,这些实现类我们无法直接访问,Guava提供了一个唯一的访问入口——MoreExecutors工具类。

1、 应用执行完成(主线程以及其他非守护线程执行完)后自动关闭的线程池

/* 执行完成后,等待terminationTimeout后关闭线程池 */
public static ExecutorService getExitingExecutorService(
ThreadPoolExecutor executor, long terminationTimeout, TimeUnit timeUnit);
/* 默认延迟120秒 */
public static ExecutorService getExitingExecutorService(ThreadPoolExecutor executor);
/* 对ScheduledExecutorService的包装 */
public static ScheduledExecutorService getExitingScheduledExecutorService(
ScheduledThreadPoolExecutor executor, long terminationTimeout, TimeUnit timeUnit);
public static ScheduledExecutorService getExitingScheduledExecutorService(
ScheduledThreadPoolExecutor executor)

这个工具方法修改传入的线程池的ThreadFactory使其生成守护线程,但是线程池使用守护进程会导致有些任务只执行了一半,为了让线程池更加可控,所以Guava使用​​Runtime.getRuntime().addShutdownHook(hook)​​注册了一个等待线程:

addShutdownHook(
MoreExecutors.newThread(
"DelayedShutdownHook-for-" + service,
new Runnable() {
@Override
public void run() {
try {
service.shutdown();
service.awaitTermination(terminationTimeout, timeUnit);
} catch (InterruptedException ignored) { }
}
}));

示例:

ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
ExecutorService executorService = MoreExecutors.getExitingExecutorService(
executor, 100, TimeUnit.MILLISECONDS);
executorService.submit(() -> { while (true) {} }); // 执行一个无限期的任务

上面的代码中,如果我们直接在线程池中执行无限期的任务,会导致JVM无限期挂起。

当我们使用​​getExitingExecutorService​​进行包装后,程序执行完后,如果线程池100毫秒内没有执行完任务,将会直接关闭线程池。

2、当前线程执行的线程池

有时可能需要在当前线程或线程池中执行任务,具体取决于某些条件,为了使用统一的接口可能需要在当前线程执行的Executor。虽然这个实现起来并不难,但还是需要编写样板代码。所幸Guava已经提供了这样的方法。

// 枚举单例
Executor executor = MoreExecutors.directExecutor();
// 每次都会创建一个新的对象
ExecutorService executor = MoreExecutors.newDirectExecutorService();

3、使用ListenableFuture异步增强的线程池

使用submit提交方式将会返回一个实现了Future接口的FutureTask对象,我们通过调用Future.get方法获取任务的执行结果,如果任务没有执行完,get方法将会导致调用线程的阻塞。为此Guava为我们提供了一个增强型的Future接口——ListenableFuture,能以异步回调的方式获取执行结果。

为了能让线程池返回ListenableFuture,MoreExecutors中提供了两个包装方法:

public static ListeningExecutorService listeningDecorator(ExecutorService delegate);
public static ListeningScheduledExecutorService listeningDecorator(ScheduledExecutorService delegate)

实际上​​ListenableFutureTask​​和上面的ExecutorComletionService一样也是通过实现FutureTask的done方法实现。

ExecutorService delegate = Executors.newCachedThreadPool();
// 包装成Guava的ListeningExecutorService
ListeningExecutorService executor = MoreExecutors.listeningDecorator(delegate);
// 提交有返回结果的任务
final ListenableFuture future = executor.submit(new Callable<Integer>() {
public Integer call() throws Exception {
int result = 0;
Thread.sleep(1000);
return result;
}
});
future.addListener(new Runable() {
public void run() {
System.out.println("result:" + future.get());
}
}, MoreExecutors.directExecutor());
// Futures工具类提供了工具方法用于任务正常或异常情况的处理。
Futures.addCallback(future, new FutureCallback<Integer>() {
public void onSuccess(Integer result) {
// 任务正常返回结果
System.out.println("result:" + result);
}
public void onFailure(Throwable t) {
// 任务抛异常了
t.printStackTrace();
}
}, MoreExecutors.directExecutor());

 

CompletionService

如果我们希望任意字任务完成后就把其结果加到result中,而不用依次等待每个任务完成,可以使CompletionService。生产者submit()执行的任务。使用者take()已完成的任务,并按照完成这些任务的顺序处理它们的结果。也就是调用CompletionService的take方法是,会返回按完成顺序放回任务的结果,CompletionService内部维护了一个阻塞队列BlockingQueue,如果没有任务完成,take()方法也会阻塞。

public class ConcurrentCalculator2 {  

private ExecutorService exec;
private CompletionService<Long> completionService;


private int cpuCoreNumber;

// 内部类
class SumCalculator implements Callable<Long> {
......
}

public ConcurrentCalculator2() {
cpuCoreNumber = Runtime.getRuntime().availableProcessors();
exec = Executors.newFixedThreadPool(cpuCoreNumber);
completionService = new ExecutorCompletionService<Long>(exec);


}

public Long sum(final int[] numbers) {
// 根据CPU核心个数拆分任务,创建FutureTask并提交到Executor
for (int i = 0; i < cpuCoreNumber; i++) {
int increment = numbers.length / cpuCoreNumber + 1;
int start = increment * i;
int end = increment * i + increment;
if (end > numbers.length)
end = numbers.length;
SumCalculator subCalc = new SumCalculator(numbers, start, end);
if (!exec.isShutdown()) {
completionService.submit(subCalc);


}

}
return getResult();
}

/**
* 迭代每个只任务,获得部分和,相加返回
*
* @return
*/
public Long getResult() {
Long result = 0l;
for (int i = 0; i < cpuCoreNumber; i++) {
try {
Long subSum = completionService.take().get();
result += subSum;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
return result;
}

public void close() {
exec.shutdown();
}
}

ExecutorCompletioService:实现了CompletionService,将执行完成的任务放到阻塞队列中,通过take或poll方法来获得执行结果

(启动10条线程,谁先执行完成就返回谁)

public class CompletionServiceTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(10); //创建含10.条线程的线程池
CompletionService completionService = new ExecutorCompletionService(executor);
for (int i =1; i <=10; i ++) {
final int result = i;
completionService.submit(new Callable() {
public Object call() throws Exception {
Thread.sleep(new Random().nextInt(5000)); //让当前线程随机休眠一段时间
return result;
}
});
}
System.out.println(completionService.take().get()); //获取执行结果
}
}

输出结果可能每次都不同(在1到10之间)

3

 

生产者与消费者多线程的使用

AtomicInteger的getAndIncrment和getAndDcrement()等方法,这些方法分为两步,get和increment(decrement),在get和increment中间可能有其他线程进入,导致多个线程get到的数值是相同的,也会导致多个线程累加后的值其实累加1.在这种情况下,使用volatile也是没有效果的,因为get之后没有对值进行修改,不能触发​​volatile​​的效果。

public class ProducerAndConsumer {
public static void main(String[] args){

try{
BlockingQueue queue = new LinkedBlockingQueue(5);

ExecutorService executor = Executors.newFixedThreadPool(5);
Produer producer = new Produer(queue);
for(int i=0;i<3;i++){
executor.execute(producer);
}
executor.execute(new Consumer(queue));

executor.shutdown();
}catch (Exception e){
e.printStackTrace();
}
}
}
class Produer implements  Runnable{

private BlockingQueue queue;
private int nums = 20; //循环次数

//标记数据编号
private static volatile AtomicInteger count = new AtomicInteger();
private boolean isRunning = true;
public Produer(){}

public Produer(BlockingQueue queue){
this.queue = queue;
}

public void run() {
String data = null;
try{
System.out.println("开始生产数据");
System.out.println("-----------------------");

while(nums>0){
nums--;
count.decrementAndGet();

Thread.sleep(500);
System.out.println(Thread.currentThread().getId()+ " :生产者生产了一个数据");
queue.put(count.getAndIncrement());
}
}catch(Exception e){
e.printStackTrace();
Thread.currentThread().interrupt();
}finally{
System.out.println("生产者线程退出!");
}
}
}
class Consumer implements Runnable{
private BlockingQueue queue;
private int nums = 20;
private boolean isRunning = true;

public Consumer(){}

public Consumer(BlockingQueue queue){
this.queue = queue;
}

public void run() {

System.out.println("消费者开始消费");
System.out.println("-------------------------");
while(nums>0){
nums--;
try{
while(isRunning){
int data = (Integer)queue.take();
Thread.sleep(500);
System.out.println("消费者消费的数据是" + data);
}

}catch(Exception e){
e.printStackTrace();
Thread.currentThread().interrupt();
}finally {
System.out.println("消费者线程退出!");
}

}
}
}

深入学习java源码之Executors.newFixedThreadPool()与Executors.newCachedThreadPool()_创建线程_08

定时任务多线程的使用

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

@SuppressWarnings({"unchecked","unused"})
public abstract class ProQuartzJob implements Job {
private ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
JobDataMap jobDataMap = arg0.getJobDetail().getJobDataMap();

final HashMap<String, Object> ibean = (HashMap<String, Object>) jobDataMap.get("DATA_BEAN");
final JobManager jobManager = (JobManager) ibean.get("CUR_OBJ");
final JobLogMapper jobLogMapper = (JobLogMapper) jobDataMap.get("jobLogMapper");
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
if(jobManager != null) {
JobLog jobLog = new JobLog();
long startTime = System.currentTimeMillis();
try {
//任务开始时间
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
jobLog.setCreateTime(sd.format(date));
jobLog.setStatus(String.valueOf(Constant.SUCCESS));
execute(ibean);
} catch (Exception e) {
jobLog.setStatus(String.valueOf(Constant.FAILED));
e.printStackTrace();
}
}else {
execute(ibean);
}
}
});
}

public abstract void execute(HashMap<String, Object> ibean);
}
public class PipOperationJob extends ProQuartzJob{
@Override
public void execute(final HashMap<String, Object> arg0) {
WorkManager.addJobByPool(arg0);
}
}
import java.text.MessageFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;


public class WorkManager {
private static Logger logger = Logger.getLogger(WorkManager.class);
// private static ExecutorService pool = Executors.newFixedThreadPool(2);
private static int queueSize = 10;
private static LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(queueSize);
private static Executor pool = new ThreadPoolExecutor(2, queueSize, 600, TimeUnit.SECONDS, queue);

public Executor getThreadPool() {
return pool;
}

public static void addJobByPool(final HashMap<String, Object> arg0) {
if(queue.size() <= 9) {
pool.execute(new Runnable() {
@Override
public void run() {
Date now = new Date();
JobManager jobManager = (JobManager) arg0.get("CUR_OBJ");
/**
* 任务调度获取表名
*/
String ruleCode = jobManager.getTaskName();
logger.info(MessageFormat.format("====sys worker {0} syn date start time:{1}====", ruleCode,
DateUtil.formatTime(now)));
/**
*
*/
new PipOperationWorker(ruleCode).synData();
Date end = new Date();
long haoshi = (now.getTime() - end.getTime()) / 1000;
logger.info(MessageFormat.format("====sys worker {0} syn date end time:{1}==haoshi:{2}==", ruleCode,
DateUtil.formatTime(end), haoshi));
}
});
}
}
}

 

java源码

Modifier and Type

Method and Description

​boolean​

​awaitTermination(long timeout, TimeUnit​

阻止所有任务在关闭请求完成后执行,或发生超时,或当前线程中断,以先到者为准。

​<T> List<Future<T>>​

​invokeAll(Collection<? extends Callable<T>> tasks)​

执行给定的任务,返回持有他们的状态和结果的所有完成的期货列表。

​<T> List<Future<T>>​

​invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit​

执行给定的任务,返回在所有完成或超时到期时持有其状态和结果的期货列表,以先发生者为准。

​<T> T​

​invokeAny(Collection<? extends Callable<T>> tasks)​

执行给定的任务,返回一个成功完成的结果(即没有抛出异常),如果有的话。

​<T> T​

​invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit​

执行给定的任务,返回一个已经成功完成的结果(即,不抛出异常),如果有的话在给定的超时之前过去。

​boolean​

​isShutdown()​

如果此执行者已关闭,则返回 ​​true​​ 。

​boolean​

​isTerminated()​

如果所有任务在关闭后完成,则返回 ​​true​​ 。

​void​

​shutdown()​

启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。

​List<Runnable>​

​shutdownNow()​

尝试停止所有主动执行的任务,停止等待任务的处理,并返回正在等待执行的任务列表。

​<T> Future<T>​

​submit(Callable<T> task)​

提交值返回任务以执行,并返回代表任务待处理结果的Future。

​Future<?>​

​submit(Runnable​

提交一个可运行的任务执行,并返回一个表示该任务的未来。

​<T> Future<T>​

​submit(Runnable​

提交一个可运行的任务执行,并返回一个表示该任务的未来。

package java.util.concurrent;
import java.util.List;
import java.util.Collection;

public interface ExecutorService extends Executor {

void shutdown();

List<Runnable> shutdownNow();

boolean isShutdown();

boolean isTerminated();

boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;

<T> Future<T> submit(Callable<T> task);

<T> Future<T> submit(Runnable task, T result);

Future<?> submit(Runnable task);

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException;

<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException;

<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}

Modifier and Type

Method and Description

​void​

​execute(Runnable​

在将来的某个时间执行给定的命令。

package java.util.concurrent;

public interface Executor {

void execute(Runnable command);
}

Modifier and Type

Method and Description

​static Callable<Object>​

​callable(PrivilegedAction<?> action)​

返回一个​​Callable​​对象,当被调用时,它运行给定的特权动作并返回其结果。

​static Callable<Object>​

​callable(PrivilegedExceptionAction<?> action)​

返回一个​​Callable​​对象,该对象在被调用时运行给定的特权异常操作并返回其结果。

​static Callable<Object>​

​callable(Runnable​

返回一个​​Callable​​对象,当被调用时,它运行给定的任务并返回​​null​​。

​static <T> Callable<T>​

​callable(Runnable​

返回一个​​Callable​​对象,当被调用时,它运行给定的任务并返回给定的结果。

​static ThreadFactory​

​defaultThreadFactory()​

返回用于创建新线程的默认线程工厂。

​static ExecutorService​

​newCachedThreadPool()​

创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。

​static ExecutorService​

​newCachedThreadPool(ThreadFactory​

创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程,并在需要时使用提供的ThreadFactory创建新线程。

​static ExecutorService​

​newFixedThreadPool(int nThreads)​

创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。

​static ExecutorService​

​newFixedThreadPool(int nThreads, ThreadFactory​

创建一个线程池,重用固定数量的线程,从共享无界队列中运行,使用提供的ThreadFactory在需要时创建新线程。

​static ScheduledExecutorService​

​newScheduledThreadPool(int corePoolSize)​

创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。

​static ScheduledExecutorService​

​newScheduledThreadPool(int corePoolSize, ThreadFactory​

创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。

​static ExecutorService​

​newSingleThreadExecutor()​

创建一个使用从无界队列运行的单个工作线程的执行程序。

​static ExecutorService​

​newSingleThreadExecutor(ThreadFactory​

创建一个使用单个工作线程运行无界队列的执行程序,并在需要时使用提供的ThreadFactory创建一个新线程。

​static ScheduledExecutorService​

​newSingleThreadScheduledExecutor()​

创建一个单线程执行器,可以调度命令在给定的延迟之后运行,或定期执行。

​static ScheduledExecutorService​

​newSingleThreadScheduledExecutor(ThreadFactory​

创建一个单线程执行器,可以调度命令在给定的延迟之后运行,或定期执行。

​static ExecutorService​

​newWorkStealingPool()​

创建使用所有​​available processors​​作为其目标并行级别的工作窃取线程池。

​static ExecutorService​

​newWorkStealingPool(int parallelism)​

创建一个维护足够的线程以支持给定的并行级别的线程池,并且可以使用多个队列来减少争用。

​static <T> Callable<T>​

​privilegedCallable(Callable<T> callable)​

返回一个​​Callable​​对象,当被调用时,将在当前访问控制上下文中执行给定的​​callable​​。

​static <T> Callable<T>​

​privilegedCallableUsingCurrentClassLoader(Callable<T> callable)​

返回一个​​Callable​​对象,当被调用时,将在当前访问控制上下文中执行给定的​​callable​​,当前上下文类加载器作为上下文类加载器。

​static ThreadFactory​

​privilegedThreadFactory()​

返回一个用于创建与当前线程具有相同权限的新线程的线程工厂。

​static ExecutorService​

​unconfigurableExecutorService(ExecutorService​

返回一个将所有定义的​​ExecutorService​​方法​​委托​​给给定执行程序的对象,但不能以其他方式使用转换方式访问。

​static ScheduledExecutorService​

​unconfigurableScheduledExecutorService(ScheduledExecutorService​

返回一个将所有定义的​​ScheduledExecutorService​​方法​​委托​​给给定执行程序的对象,但不能以其他方式使用转换方式访问。

package java.util.concurrent;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import java.security.AccessControlException;
import sun.security.util.SecurityConstants;


public class Executors {

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}

public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}

public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}

public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}

public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1, threadFactory));
}

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}

public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}

public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
if (executor == null)
throw new NullPointerException();
return new DelegatedExecutorService(executor);
}

public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {
if (executor == null)
throw new NullPointerException();
return new DelegatedScheduledExecutorService(executor);
}

public static ThreadFactory defaultThreadFactory() {
return new DefaultThreadFactory();
}

public static ThreadFactory privilegedThreadFactory() {
return new PrivilegedThreadFactory();
}

public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}

public static Callable<Object> callable(Runnable task) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<Object>(task, null);
}

public static Callable<Object> callable(final PrivilegedAction<?> action) {
if (action == null)
throw new NullPointerException();
return new Callable<Object>() {
public Object call() { return action.run(); }};
}

public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {
if (action == null)
throw new NullPointerException();
return new Callable<Object>() {
public Object call() throws Exception { return action.run(); }};
}

public static <T> Callable<T> privilegedCallable(Callable<T> callable) {
if (callable == null)
throw new NullPointerException();
return new PrivilegedCallable<T>(callable);
}

public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) {
if (callable == null)
throw new NullPointerException();
return new PrivilegedCallableUsingCurrentClassLoader<T>(callable);
}

// Non-public classes supporting the public methods
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}

static final class PrivilegedCallable<T> implements Callable<T> {
private final Callable<T> task;
private final AccessControlContext acc;

PrivilegedCallable(Callable<T> task) {
this.task = task;
this.acc = AccessController.getContext();
}

public T call() throws Exception {
try {
return AccessController.doPrivileged(
new PrivilegedExceptionAction<T>() {
public T run() throws Exception {
return task.call();
}
}, acc);
} catch (PrivilegedActionException e) {
throw e.getException();
}
}
}

static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
private final Callable<T> task;
private final AccessControlContext acc;
private final ClassLoader ccl;

PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Calls to getContextClassLoader from this class
// never trigger a security check, but we check
// whether our callers have this permission anyways.
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);

// Whether setContextClassLoader turns out to be necessary
// or not, we fail fast if permission is not available.
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
this.task = task;
this.acc = AccessController.getContext();
this.ccl = Thread.currentThread().getContextClassLoader();
}

public T call() throws Exception {
try {
return AccessController.doPrivileged(
new PrivilegedExceptionAction<T>() {
public T run() throws Exception {
Thread t = Thread.currentThread();
ClassLoader cl = t.getContextClassLoader();
if (ccl == cl) {
return task.call();
} else {
t.setContextClassLoader(ccl);
try {
return task.call();
} finally {
t.setContextClassLoader(cl);
}
}
}
}, acc);
} catch (PrivilegedActionException e) {
throw e.getException();
}
}
}

static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;

DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-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;
}
}

static class PrivilegedThreadFactory extends DefaultThreadFactory {
private final AccessControlContext acc;
private final ClassLoader ccl;

PrivilegedThreadFactory() {
super();
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Calls to getContextClassLoader from this class
// never trigger a security check, but we check
// whether our callers have this permission anyways.
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);

// Fail fast
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
this.acc = AccessController.getContext();
this.ccl = Thread.currentThread().getContextClassLoader();
}

public Thread newThread(final Runnable r) {
return super.newThread(new Runnable() {
public void run() {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
Thread.currentThread().setContextClassLoader(ccl);
r.run();
return null;
}
}, acc);
}
});
}
}

static class DelegatedExecutorService extends AbstractExecutorService {
private final ExecutorService e;
DelegatedExecutorService(ExecutorService executor) { e = executor; }
public void execute(Runnable command) { e.execute(command); }
public void shutdown() { e.shutdown(); }
public List<Runnable> shutdownNow() { return e.shutdownNow(); }
public boolean isShutdown() { return e.isShutdown(); }
public boolean isTerminated() { return e.isTerminated(); }
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
return e.awaitTermination(timeout, unit);
}
public Future<?> submit(Runnable task) {
return e.submit(task);
}
public <T> Future<T> submit(Callable<T> task) {
return e.submit(task);
}
public <T> Future<T> submit(Runnable task, T result) {
return e.submit(task, result);
}
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
return e.invokeAll(tasks);
}
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException {
return e.invokeAll(tasks, timeout, unit);
}
public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException {
return e.invokeAny(tasks);
}
public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return e.invokeAny(tasks, timeout, unit);
}
}

static class FinalizableDelegatedExecutorService
extends DelegatedExecutorService {
FinalizableDelegatedExecutorService(ExecutorService executor) {
super(executor);
}
protected void finalize() {
super.shutdown();
}
}

static class DelegatedScheduledExecutorService
extends DelegatedExecutorService
implements ScheduledExecutorService {
private final ScheduledExecutorService e;
DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
super(executor);
e = executor;
}
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
return e.schedule(command, delay, unit);
}
public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
return e.schedule(callable, delay, unit);
}
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
return e.scheduleAtFixedRate(command, initialDelay, period, unit);
}
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);
}
}

/** Cannot instantiate. */
private Executors() {}
}

 

Modifier and Type

Method and Description

​<T> List<Future<T>>​

​invokeAll(Collection<? extends Callable<T>> tasks)​

执行给定的任务,返回持有他们的状态和结果的所有完成的期货列表。

​<T> List<Future<T>>​

​invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit​

执行给定的任务,返回在所有完成或超时到期时持有其状态和结果的期货列表,以先发生者为准。

​<T> T​

​invokeAny(Collection<? extends Callable<T>> tasks)​

执行给定的任务,返回一个成功完成的结果(即没有抛出异常),如果有的话。

​<T> T​

​invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit​

执行给定的任务,返回一个已经成功完成的结果(即,不抛出异常),如果有的话在给定的超时之前过去。

​protected <T> RunnableFuture<T>​

​newTaskFor(Callable<T> callable)​

返回给定可调用任务的​​RunnableFuture​​。

​protected <T> RunnableFuture<T>​

​newTaskFor(Runnable​

对于给定的可运行和默认值,返回一个​​RunnableFuture​​。

​<T> Future<T>​

​submit(Callable<T> task)​

提交值返回任务以执行,并返回代表任务待处理结果的Future。

​Future<?>​

​submit(Runnable​

提交一个可运行的任务执行,并返回一个表示该任务的未来。

​<T> Future<T>​

​submit(Runnable​

提交一个可运行的任务执行,并返回一个表示该任务的未来。

package java.util.concurrent;
import java.util.*;


public abstract class AbstractExecutorService implements ExecutorService {

protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}

protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}

public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}

public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}

public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}

private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
boolean timed, long nanos)
throws InterruptedException, ExecutionException, TimeoutException {
if (tasks == null)
throw new NullPointerException();
int ntasks = tasks.size();
if (ntasks == 0)
throw new IllegalArgumentException();
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
ExecutorCompletionService<T> ecs =
new ExecutorCompletionService<T>(this);

// For efficiency, especially in executors with limited
// parallelism, check to see if previously submitted tasks are
// done before submitting more of them. This interleaving
// plus the exception mechanics account for messiness of main
// loop.

try {
// Record exceptions so that if we fail to obtain any
// result, we can throw the last exception we got.
ExecutionException ee = null;
final long deadline = timed ? System.nanoTime() + nanos : 0L;
Iterator<? extends Callable<T>> it = tasks.iterator();

// Start one task for sure; the rest incrementally
futures.add(ecs.submit(it.next()));
--ntasks;
int active = 1;

for (;;) {
Future<T> f = ecs.poll();
if (f == null) {
if (ntasks > 0) {
--ntasks;
futures.add(ecs.submit(it.next()));
++active;
}
else if (active == 0)
break;
else if (timed) {
f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
if (f == null)
throw new TimeoutException();
nanos = deadline - System.nanoTime();
}
else
f = ecs.take();
}
if (f != null) {
--active;
try {
return f.get();
} catch (ExecutionException eex) {
ee = eex;
} catch (RuntimeException rex) {
ee = new ExecutionException(rex);
}
}
}

if (ee == null)
ee = new ExecutionException();
throw ee;

} finally {
for (int i = 0, size = futures.size(); i < size; i++)
futures.get(i).cancel(true);
}
}

public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException {
try {
return doInvokeAny(tasks, false, 0);
} catch (TimeoutException cannotHappen) {
assert false;
return null;
}
}

public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return doInvokeAny(tasks, true, unit.toNanos(timeout));
}

public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
if (tasks == null)
throw new NullPointerException();
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
for (Callable<T> t : tasks) {
RunnableFuture<T> f = newTaskFor(t);
futures.add(f);
execute(f);
}
for (int i = 0, size = futures.size(); i < size; i++) {
Future<T> f = futures.get(i);
if (!f.isDone()) {
try {
f.get();
} catch (CancellationException ignore) {
} catch (ExecutionException ignore) {
}
}
}
done = true;
return futures;
} finally {
if (!done)
for (int i = 0, size = futures.size(); i < size; i++)
futures.get(i).cancel(true);
}
}

public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException {
if (tasks == null)
throw new NullPointerException();
long nanos = unit.toNanos(timeout);
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
for (Callable<T> t : tasks)
futures.add(newTaskFor(t));

final long deadline = System.nanoTime() + nanos;
final int size = futures.size();

// Interleave time checks and calls to execute in case
// executor doesn't have any/much parallelism.
for (int i = 0; i < size; i++) {
execute((Runnable)futures.get(i));
nanos = deadline - System.nanoTime();
if (nanos <= 0L)
return futures;
}

for (int i = 0; i < size; i++) {
Future<T> f = futures.get(i);
if (!f.isDone()) {
if (nanos <= 0L)
return futures;
try {
f.get(nanos, TimeUnit.NANOSECONDS);
} catch (CancellationException ignore) {
} catch (ExecutionException ignore) {
} catch (TimeoutException toe) {
return futures;
}
nanos = deadline - System.nanoTime();
}
}
done = true;
return futures;
} finally {
if (!done)
for (int i = 0, size = futures.size(); i < size; i++)
futures.get(i).cancel(true);
}
}

}

 

Modifier and Type

Method and Description

​<V> ScheduledFuture<V>​

​schedule(Callable<V> callable, long delay, TimeUnit​

创建并执行在给定延迟后启用的ScheduledFuture。

​ScheduledFuture<?>​

​schedule(Runnable command, long delay, TimeUnit​

创建并执行在给定延迟后启用的单次操作。

​ScheduledFuture<?>​

​scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit​

创建并执行在给定的初始延迟之后,随后以给定的时间段首先启用的周期性动作;那就是执行将在​​initialDelay​​​之后开始,然后是​​initialDelay+period​​​,然后是​​initialDelay + 2 * period​​,等等。

​ScheduledFuture<?>​

​scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit​

创建并执行在给定的初始延迟之后首先启用的定期动作,随后在一个执行的终止和下一个执行的开始之间给定的延迟。

package java.util.concurrent;

public interface ScheduledExecutorService extends ExecutorService {

public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit);

public <V> ScheduledFuture<V> schedule(Callable<V> callable,
long delay, TimeUnit unit);

public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);

public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);

}

 

Modifier and Type

Class and Description

​static class ​

​ThreadPoolExecutor.AbortPolicy​

被拒绝的任务的处理程序,抛出一个​​RejectedExecutionException​​。

​static class ​

​ThreadPoolExecutor.CallerRunsPolicy​

一个被拒绝的任务的处理程序,直接在​​execute​​方法的调用线程中运行被拒绝的任务,除非执行程序已经被关闭,否则这个任务被丢弃。

​static class ​

​ThreadPoolExecutor.DiscardOldestPolicy​

被拒绝的任务的处理程序,丢弃最旧的未处理请求,然后重试​​execute​​,除非执行程序关闭,在这种情况下,任务被丢弃。

​static class ​

​ThreadPoolExecutor.DiscardPolicy​

被拒绝的任务的处理程序静默地丢弃被拒绝的任务。

package java.util.concurrent;

import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.*;

public class ThreadPoolExecutor extends AbstractExecutorService {

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;

// runState is stored in the high-order bits
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;

// Packing and unpacking ctl
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }

private static boolean runStateLessThan(int c, int s) {
return c < s;
}

private static boolean runStateAtLeast(int c, int s) {
return c >= s;
}

private static boolean isRunning(int c) {
return c < SHUTDOWN;
}

private boolean compareAndIncrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}

private boolean compareAndDecrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect - 1);
}

private void decrementWorkerCount() {
do {} while (! compareAndDecrementWorkerCount(ctl.get()));
}

private final BlockingQueue<Runnable> workQueue;

private final ReentrantLock mainLock = new ReentrantLock();

private final HashSet<Worker> workers = new HashSet<Worker>();

private final Condition termination = mainLock.newCondition();

private int largestPoolSize;

private long completedTaskCount;

private volatile ThreadFactory threadFactory;

private volatile RejectedExecutionHandler handler;

private volatile long keepAliveTime;

private volatile boolean allowCoreThreadTimeOut;

private volatile int corePoolSize;

private volatile int maximumPoolSize;

private static final RejectedExecutionHandler defaultHandler =
new AbortPolicy();

private static final RuntimePermission shutdownPerm =
new RuntimePermission("modifyThread");

/* The context to be used when executing the finalizer, or null. */
private final AccessControlContext acc;

private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
/**
* This class will never be serialized, but we provide a
* serialVersionUID to suppress a javac warning.
*/
private static final long serialVersionUID = 6138294804551838833L;

/** Thread this worker is running in. Null if factory fails. */
final Thread thread;
/** Initial task to run. Possibly null. */
Runnable firstTask;
/** Per-thread task counter */
volatile long completedTasks;

/**
* Creates with given first task and thread from ThreadFactory.
* @param firstTask the first task (null if none)
*/
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}

/** Delegates main run loop to outer runWorker */
public void run() {
runWorker(this);
}

// Lock methods
//
// The value 0 represents the unlocked state.
// The value 1 represents the locked state.

protected boolean isHeldExclusively() {
return getState() != 0;
}

protected boolean tryAcquire(int unused) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}

protected boolean tryRelease(int unused) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}

public void lock() { acquire(1); }
public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); }

void interruptIfStarted() {
Thread t;
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
}
}
}
}

private void advanceRunState(int targetState) {
for (;;) {
int c = ctl.get();
if (runStateAtLeast(c, targetState) ||
ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
break;
}
}

final void tryTerminate() {
for (;;) {
int c = ctl.get();
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}

final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
terminated();
} finally {
ctl.set(ctlOf(TERMINATED, 0));
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}

private void checkShutdownAccess() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(shutdownPerm);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
security.checkAccess(w.thread);
} finally {
mainLock.unlock();
}
}
}

private void interruptWorkers() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
w.interruptIfStarted();
} finally {
mainLock.unlock();
}
}

private void interruptIdleWorkers(boolean onlyOne) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers) {
Thread t = w.thread;
if (!t.isInterrupted() && w.tryLock()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
} finally {
w.unlock();
}
}
if (onlyOne)
break;
}
} finally {
mainLock.unlock();
}
}

private void interruptIdleWorkers() {
interruptIdleWorkers(false);
}

private static final boolean ONLY_ONE = true;

final void reject(Runnable command) {
handler.rejectedExecution(command, this);
}

void onShutdown() {
}

final boolean isRunningOrShutdown(boolean shutdownOK) {
int rs = runStateOf(ctl.get());
return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
}

private List<Runnable> drainQueue() {
BlockingQueue<Runnable> q = workQueue;
ArrayList<Runnable> taskList = new ArrayList<Runnable>();
q.drainTo(taskList);
if (!q.isEmpty()) {
for (Runnable r : q.toArray(new Runnable[0])) {
if (q.remove(r))
taskList.add(r);
}
}
return taskList;
}

private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);

// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;

for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}

boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());

if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}

private void addWorkerFailed(Worker w) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (w != null)
workers.remove(w);
decrementWorkerCount();
tryTerminate();
} finally {
mainLock.unlock();
}
}

private void processWorkerExit(Worker w, boolean completedAbruptly) {
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();

final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
workers.remove(w);
} finally {
mainLock.unlock();
}

tryTerminate();

int c = ctl.get();
if (runStateLessThan(c, STOP)) {
if (!completedAbruptly) {
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min)
return; // replacement not needed
}
addWorker(null, false);
}
}

private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?

for (;;) {
int c = ctl.get();
int rs = runStateOf(c);

// Check if queue empty only if necessary.
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}

int wc = workerCountOf(c);

// Are workers subject to culling?
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}

try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}

final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}

// Public constructors and methods
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}

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.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}

public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}

public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
advanceRunState(SHUTDOWN);
interruptIdleWorkers();
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
mainLock.unlock();
}
tryTerminate();
}

public List<Runnable> shutdownNow() {
List<Runnable> tasks;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
advanceRunState(STOP);
interruptWorkers();
tasks = drainQueue();
} finally {
mainLock.unlock();
}
tryTerminate();
return tasks;
}

public boolean isShutdown() {
return ! isRunning(ctl.get());
}

public boolean isTerminating() {
int c = ctl.get();
return ! isRunning(c) && runStateLessThan(c, TERMINATED);
}

public boolean isTerminated() {
return runStateAtLeast(ctl.get(), TERMINATED);
}

public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
long nanos = unit.toNanos(timeout);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (;;) {
if (runStateAtLeast(ctl.get(), TERMINATED))
return true;
if (nanos <= 0)
return false;
nanos = termination.awaitNanos(nanos);
}
} finally {
mainLock.unlock();
}
}

protected void finalize() {
SecurityManager sm = System.getSecurityManager();
if (sm == null || acc == null) {
shutdown();
} else {
PrivilegedAction<Void> pa = () -> { shutdown(); return null; };
AccessController.doPrivileged(pa, acc);
}
}

public void setThreadFactory(ThreadFactory threadFactory) {
if (threadFactory == null)
throw new NullPointerException();
this.threadFactory = threadFactory;
}

public ThreadFactory getThreadFactory() {
return threadFactory;
}

public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
if (handler == null)
throw new NullPointerException();
this.handler = handler;
}

public RejectedExecutionHandler getRejectedExecutionHandler() {
return handler;
}

public void setCorePoolSize(int corePoolSize) {
if (corePoolSize < 0)
throw new IllegalArgumentException();
int delta = corePoolSize - this.corePoolSize;
this.corePoolSize = corePoolSize;
if (workerCountOf(ctl.get()) > corePoolSize)
interruptIdleWorkers();
else if (delta > 0) {
// We don't really know how many new threads are "needed".
// As a heuristic, prestart enough new workers (up to new
// core size) to handle the current number of tasks in
// queue, but stop if queue becomes empty while doing so.
int k = Math.min(delta, workQueue.size());
while (k-- > 0 && addWorker(null, true)) {
if (workQueue.isEmpty())
break;
}
}
}

public int getCorePoolSize() {
return corePoolSize;
}

public boolean prestartCoreThread() {
return workerCountOf(ctl.get()) < corePoolSize &&
addWorker(null, true);
}

void ensurePrestart() {
int wc = workerCountOf(ctl.get());
if (wc < corePoolSize)
addWorker(null, true);
else if (wc == 0)
addWorker(null, false);
}

public int prestartAllCoreThreads() {
int n = 0;
while (addWorker(null, true))
++n;
return n;
}

public boolean allowsCoreThreadTimeOut() {
return allowCoreThreadTimeOut;
}

public void allowCoreThreadTimeOut(boolean value) {
if (value && keepAliveTime <= 0)
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
if (value != allowCoreThreadTimeOut) {
allowCoreThreadTimeOut = value;
if (value)
interruptIdleWorkers();
}
}

public void setMaximumPoolSize(int maximumPoolSize) {
if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
throw new IllegalArgumentException();
this.maximumPoolSize = maximumPoolSize;
if (workerCountOf(ctl.get()) > maximumPoolSize)
interruptIdleWorkers();
}

public int getMaximumPoolSize() {
return maximumPoolSize;
}

public void setKeepAliveTime(long time, TimeUnit unit) {
if (time < 0)
throw new IllegalArgumentException();
if (time == 0 && allowsCoreThreadTimeOut())
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
long keepAliveTime = unit.toNanos(time);
long delta = keepAliveTime - this.keepAliveTime;
this.keepAliveTime = keepAliveTime;
if (delta < 0)
interruptIdleWorkers();
}

public long getKeepAliveTime(TimeUnit unit) {
return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
}

/* User-level queue utilities */
public BlockingQueue<Runnable> getQueue() {
return workQueue;
}

public boolean remove(Runnable task) {
boolean removed = workQueue.remove(task);
tryTerminate(); // In case SHUTDOWN and now empty
return removed;
}

public void purge() {
final BlockingQueue<Runnable> q = workQueue;
try {
Iterator<Runnable> it = q.iterator();
while (it.hasNext()) {
Runnable r = it.next();
if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
it.remove();
}
} catch (ConcurrentModificationException fallThrough) {
// Take slow path if we encounter interference during traversal.
// Make copy for traversal and call remove for cancelled entries.
// The slow path is more likely to be O(N*N).
for (Object r : q.toArray())
if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
q.remove(r);
}

tryTerminate(); // In case SHUTDOWN and now empty
}

public int getPoolSize() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Remove rare and surprising possibility of
// isTerminated() && getPoolSize() > 0
return runStateAtLeast(ctl.get(), TIDYING) ? 0
: workers.size();
} finally {
mainLock.unlock();
}
}

public int getActiveCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
int n = 0;
for (Worker w : workers)
if (w.isLocked())
++n;
return n;
} finally {
mainLock.unlock();
}
}

public int getLargestPoolSize() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
return largestPoolSize;
} finally {
mainLock.unlock();
}
}

public long getTaskCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
long n = completedTaskCount;
for (Worker w : workers) {
n += w.completedTasks;
if (w.isLocked())
++n;
}
return n + workQueue.size();
} finally {
mainLock.unlock();
}
}

public long getCompletedTaskCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
long n = completedTaskCount;
for (Worker w : workers)
n += w.completedTasks;
return n;
} finally {
mainLock.unlock();
}
}

public String toString() {
long ncompleted;
int nworkers, nactive;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
ncompleted = completedTaskCount;
nactive = 0;
nworkers = workers.size();
for (Worker w : workers) {
ncompleted += w.completedTasks;
if (w.isLocked())
++nactive;
}
} finally {
mainLock.unlock();
}
int c = ctl.get();
String rs = (runStateLessThan(c, SHUTDOWN) ? "Running" :
(runStateAtLeast(c, TERMINATED) ? "Terminated" :
"Shutting down"));
return super.toString() +
"[" + rs +
", pool size = " + nworkers +
", active threads = " + nactive +
", queued tasks = " + workQueue.size() +
", completed tasks = " + ncompleted +
"]";
}

protected void beforeExecute(Thread t, Runnable r) { }

protected void afterExecute(Runnable r, Throwable t) { }

protected void terminated() { }

public static class CallerRunsPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code CallerRunsPolicy}.
*/
public CallerRunsPolicy() { }

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
}

public static class AbortPolicy implements RejectedExecutionHandler {
/**
* Creates an {@code AbortPolicy}.
*/
public AbortPolicy() { }

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}

public static class DiscardPolicy implements RejectedExecutionHandler {

public DiscardPolicy() { }

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
}

public static class DiscardOldestPolicy implements RejectedExecutionHandler {

public DiscardOldestPolicy() { }

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
}
}

 

Modifier and Type

Method and Description

​protected <V> RunnableScheduledFuture<V>​

​decorateTask(Callable<V> callable, RunnableScheduledFuture<V> task)​

修改或替换用于执行可调用的任务。

​protected <V> RunnableScheduledFuture<V>​

​decorateTask(Runnable runnable, RunnableScheduledFuture<V> task)​

修改或替换用于执行runnable的任务。

​void​

​execute(Runnable​

执行​​command​​零要求延迟。

​boolean​

​getContinueExistingPeriodicTasksAfterShutdownPolicy()​

获得关于是否继续执行现有定期任务的策略,即使该执行者已经是​​shutdown​​。

​boolean​

​getExecuteExistingDelayedTasksAfterShutdownPolicy()​

获得有关是否执行现有延迟任务的政策,即使这个执行者已经是​​shutdown​​。

​BlockingQueue<Runnable>​

​getQueue()​

返回此执行程序使用的任务队列。

​boolean​

​getRemoveOnCancelPolicy()​

获取关于在取消时是否应立即将已取消任务从工作队列中删除的策略。

​<V> ScheduledFuture<V>​

​schedule(Callable<V> callable, long delay, TimeUnit​

创建并执行在给定延迟后启用的ScheduledFuture。

​ScheduledFuture<?>​

​schedule(Runnable command, long delay, TimeUnit​

创建并执行在给定延迟后启用的单次操作。

​ScheduledFuture<?>​

​scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit​

创建并执行在给定的初始延迟之后,随后以给定的时间段首先启用的周期性动作;那就是执行将在​​initialDelay​​​之后开始,然后​​initialDelay+period​​​,然后是​​initialDelay + 2 * period​​等等。

​ScheduledFuture<?>​

​scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit​

创建并执行在给定的初始延迟之后首先启用的定期动作,随后在一个执行的终止和下一个执行的开始之间给定的延迟。

​void​

​setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value)​

设置关于是否继续执行现有周期性任务的策略,即使该执行者已经是​​shutdown​​。

​void​

​setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value)​

设置关于是否执行现有延迟任务的策略,即使该执行者已经是​​shutdown​​。

​void​

​setRemoveOnCancelPolicy(boolean value)​

设置取消时取消任务是否应立即从工作队列中删除的策略。

​void​

​shutdown()​

启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。

​List<Runnable>​

​shutdownNow()​

尝试停止所有主动执行的任务,停止等待任务的处理,并返回正在等待执行的任务列表。

​<T> Future<T>​

​submit(Callable<T> task)​

提交值返回任务以执行,并返回代表任务待处理结果的Future。

​Future<?>​

​submit(Runnable​

提交一个可运行的任务执行,并返回一个表示该任务的未来。

​<T> Future<T>​

​submit(Runnable​

提交一个可运行的任务执行,并返回一个表示该任务的未来。

package java.util.concurrent;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.*;

public class ScheduledThreadPoolExecutor
extends ThreadPoolExecutor
implements ScheduledExecutorService {

private volatile boolean continueExistingPeriodicTasksAfterShutdown;

private volatile boolean executeExistingDelayedTasksAfterShutdown = true;

private volatile boolean removeOnCancel = false;

private static final AtomicLong sequencer = new AtomicLong();

final long now() {
return System.nanoTime();
}

private class ScheduledFutureTask<V>
extends FutureTask<V> implements RunnableScheduledFuture<V> {

/** Sequence number to break ties FIFO */
private final long sequenceNumber;

/** The time the task is enabled to execute in nanoTime units */
private long time;

private final long period;

/** The actual task to be re-enqueued by reExecutePeriodic */
RunnableScheduledFuture<V> outerTask = this;

int heapIndex;

ScheduledFutureTask(Runnable r, V result, long ns) {
super(r, result);
this.time = ns;
this.period = 0;
this.sequenceNumber = sequencer.getAndIncrement();
}

ScheduledFutureTask(Runnable r, V result, long ns, long period) {
super(r, result);
this.time = ns;
this.period = period;
this.sequenceNumber = sequencer.getAndIncrement();
}

ScheduledFutureTask(Callable<V> callable, long ns) {
super(callable);
this.time = ns;
this.period = 0;
this.sequenceNumber = sequencer.getAndIncrement();
}

public long getDelay(TimeUnit unit) {
return unit.convert(time - now(), NANOSECONDS);
}

public int compareTo(Delayed other) {
if (other == this) // compare zero if same object
return 0;
if (other instanceof ScheduledFutureTask) {
ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
long diff = time - x.time;
if (diff < 0)
return -1;
else if (diff > 0)
return 1;
else if (sequenceNumber < x.sequenceNumber)
return -1;
else
return 1;
}
long diff = getDelay(NANOSECONDS) - other.getDelay(NANOSECONDS);
return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
}

public boolean isPeriodic() {
return period != 0;
}

private void setNextRunTime() {
long p = period;
if (p > 0)
time += p;
else
time = triggerTime(-p);
}

public boolean cancel(boolean mayInterruptIfRunning) {
boolean cancelled = super.cancel(mayInterruptIfRunning);
if (cancelled && removeOnCancel && heapIndex >= 0)
remove(this);
return cancelled;
}

public void run() {
boolean periodic = isPeriodic();
if (!canRunInCurrentRunState(periodic))
cancel(false);
else if (!periodic)
ScheduledFutureTask.super.run();
else if (ScheduledFutureTask.super.runAndReset()) {
setNextRunTime();
reExecutePeriodic(outerTask);
}
}
}

boolean canRunInCurrentRunState(boolean periodic) {
return isRunningOrShutdown(periodic ?
continueExistingPeriodicTasksAfterShutdown :
executeExistingDelayedTasksAfterShutdown);
}

private void delayedExecute(RunnableScheduledFuture<?> task) {
if (isShutdown())
reject(task);
else {
super.getQueue().add(task);
if (isShutdown() &&
!canRunInCurrentRunState(task.isPeriodic()) &&
remove(task))
task.cancel(false);
else
ensurePrestart();
}
}

void reExecutePeriodic(RunnableScheduledFuture<?> task) {
if (canRunInCurrentRunState(true)) {
super.getQueue().add(task);
if (!canRunInCurrentRunState(true) && remove(task))
task.cancel(false);
else
ensurePrestart();
}
}

@Override void onShutdown() {
BlockingQueue<Runnable> q = super.getQueue();
boolean keepDelayed =
getExecuteExistingDelayedTasksAfterShutdownPolicy();
boolean keepPeriodic =
getContinueExistingPeriodicTasksAfterShutdownPolicy();
if (!keepDelayed && !keepPeriodic) {
for (Object e : q.toArray())
if (e instanceof RunnableScheduledFuture<?>)
((RunnableScheduledFuture<?>) e).cancel(false);
q.clear();
}
else {
// Traverse snapshot to avoid iterator exceptions
for (Object e : q.toArray()) {
if (e instanceof RunnableScheduledFuture) {
RunnableScheduledFuture<?> t =
(RunnableScheduledFuture<?>)e;
if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) ||
t.isCancelled()) { // also remove if already cancelled
if (q.remove(t))
t.cancel(false);
}
}
}
}
tryTerminate();
}

protected <V> RunnableScheduledFuture<V> decorateTask(
Runnable runnable, RunnableScheduledFuture<V> task) {
return task;
}

protected <V> RunnableScheduledFuture<V> decorateTask(
Callable<V> callable, RunnableScheduledFuture<V> task) {
return task;
}

public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}

public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
}

public ScheduledThreadPoolExecutor(int corePoolSize,
RejectedExecutionHandler handler) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue(), handler);
}

public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue(), threadFactory, handler);
}

private long triggerTime(long delay, TimeUnit unit) {
return triggerTime(unit.toNanos((delay < 0) ? 0 : delay));
}

long triggerTime(long delay) {
return now() +
((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));
}

private long overflowFree(long delay) {
Delayed head = (Delayed) super.getQueue().peek();
if (head != null) {
long headDelay = head.getDelay(NANOSECONDS);
if (headDelay < 0 && (delay - headDelay < 0))
delay = Long.MAX_VALUE + headDelay;
}
return delay;
}

public ScheduledFuture<?> schedule(Runnable command,
long delay,
TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
RunnableScheduledFuture<?> t = decorateTask(command,
new ScheduledFutureTask<Void>(command, null,
triggerTime(delay, unit)));
delayedExecute(t);
return t;
}

public <V> ScheduledFuture<V> schedule(Callable<V> callable,
long delay,
TimeUnit unit) {
if (callable == null || unit == null)
throw new NullPointerException();
RunnableScheduledFuture<V> t = decorateTask(callable,
new ScheduledFutureTask<V>(callable,
triggerTime(delay, unit)));
delayedExecute(t);
return t;
}

public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
if (period <= 0)
throw new IllegalArgumentException();
ScheduledFutureTask<Void> sft =
new ScheduledFutureTask<Void>(command,
null,
triggerTime(initialDelay, unit),
unit.toNanos(period));
RunnableScheduledFuture<Void> t = decorateTask(command, sft);
sft.outerTask = t;
delayedExecute(t);
return t;
}

public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
if (delay <= 0)
throw new IllegalArgumentException();
ScheduledFutureTask<Void> sft =
new ScheduledFutureTask<Void>(command,
null,
triggerTime(initialDelay, unit),
unit.toNanos(-delay));
RunnableScheduledFuture<Void> t = decorateTask(command, sft);
sft.outerTask = t;
delayedExecute(t);
return t;
}

public void execute(Runnable command) {
schedule(command, 0, NANOSECONDS);
}

// Override AbstractExecutorService methods
public Future<?> submit(Runnable task) {
return schedule(task, 0, NANOSECONDS);
}

public <T> Future<T> submit(Runnable task, T result) {
return schedule(Executors.callable(task, result), 0, NANOSECONDS);
}

public <T> Future<T> submit(Callable<T> task) {
return schedule(task, 0, NANOSECONDS);
}

public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) {
continueExistingPeriodicTasksAfterShutdown = value;
if (!value && isShutdown())
onShutdown();
}

public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() {
return continueExistingPeriodicTasksAfterShutdown;
}

public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) {
executeExistingDelayedTasksAfterShutdown = value;
if (!value && isShutdown())
onShutdown();
}

public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() {
return executeExistingDelayedTasksAfterShutdown;
}

public void setRemoveOnCancelPolicy(boolean value) {
removeOnCancel = value;
}

public boolean getRemoveOnCancelPolicy() {
return removeOnCancel;
}

public void shutdown() {
super.shutdown();
}

public List<Runnable> shutdownNow() {
return super.shutdownNow();
}

public BlockingQueue<Runnable> getQueue() {
return super.getQueue();
}

static class DelayedWorkQueue extends AbstractQueue<Runnable>
implements BlockingQueue<Runnable> {

private static final int INITIAL_CAPACITY = 16;
private RunnableScheduledFuture<?>[] queue =
new RunnableScheduledFuture<?>[INITIAL_CAPACITY];
private final ReentrantLock lock = new ReentrantLock();
private int size = 0;

private Thread leader = null;

/**
* Condition signalled when a newer task becomes available at the
* head of the queue or a new thread may need to become leader.
*/
private final Condition available = lock.newCondition();

/**
* Sets f's heapIndex if it is a ScheduledFutureTask.
*/
private void setIndex(RunnableScheduledFuture<?> f, int idx) {
if (f instanceof ScheduledFutureTask)
((ScheduledFutureTask)f).heapIndex = idx;
}

private void siftUp(int k, RunnableScheduledFuture<?> key) {
while (k > 0) {
int parent = (k - 1) >>> 1;
RunnableScheduledFuture<?> e = queue[parent];
if (key.compareTo(e) >= 0)
break;
queue[k] = e;
setIndex(e, k);
k = parent;
}
queue[k] = key;
setIndex(key, k);
}

private void siftDown(int k, RunnableScheduledFuture<?> key) {
int half = size >>> 1;
while (k < half) {
int child = (k << 1) + 1;
RunnableScheduledFuture<?> c = queue[child];
int right = child + 1;
if (right < size && c.compareTo(queue[right]) > 0)
c = queue[child = right];
if (key.compareTo(c) <= 0)
break;
queue[k] = c;
setIndex(c, k);
k = child;
}
queue[k] = key;
setIndex(key, k);
}

private void grow() {
int oldCapacity = queue.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); // grow 50%
if (newCapacity < 0) // overflow
newCapacity = Integer.MAX_VALUE;
queue = Arrays.copyOf(queue, newCapacity);
}

private int indexOf(Object x) {
if (x != null) {
if (x instanceof ScheduledFutureTask) {
int i = ((ScheduledFutureTask) x).heapIndex;
// Sanity check; x could conceivably be a
// ScheduledFutureTask from some other pool.
if (i >= 0 && i < size && queue[i] == x)
return i;
} else {
for (int i = 0; i < size; i++)
if (x.equals(queue[i]))
return i;
}
}
return -1;
}

public boolean contains(Object x) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return indexOf(x) != -1;
} finally {
lock.unlock();
}
}

public boolean remove(Object x) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
int i = indexOf(x);
if (i < 0)
return false;

setIndex(queue[i], -1);
int s = --size;
RunnableScheduledFuture<?> replacement = queue[s];
queue[s] = null;
if (s != i) {
siftDown(i, replacement);
if (queue[i] == replacement)
siftUp(i, replacement);
}
return true;
} finally {
lock.unlock();
}
}

public int size() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return size;
} finally {
lock.unlock();
}
}

public boolean isEmpty() {
return size() == 0;
}

public int remainingCapacity() {
return Integer.MAX_VALUE;
}

public RunnableScheduledFuture<?> peek() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return queue[0];
} finally {
lock.unlock();
}
}

public boolean offer(Runnable x) {
if (x == null)
throw new NullPointerException();
RunnableScheduledFuture<?> e = (RunnableScheduledFuture<?>)x;
final ReentrantLock lock = this.lock;
lock.lock();
try {
int i = size;
if (i >= queue.length)
grow();
size = i + 1;
if (i == 0) {
queue[0] = e;
setIndex(e, 0);
} else {
siftUp(i, e);
}
if (queue[0] == e) {
leader = null;
available.signal();
}
} finally {
lock.unlock();
}
return true;
}

public void put(Runnable e) {
offer(e);
}

public boolean add(Runnable e) {
return offer(e);
}

public boolean offer(Runnable e, long timeout, TimeUnit unit) {
return offer(e);
}

private RunnableScheduledFuture<?> finishPoll(RunnableScheduledFuture<?> f) {
int s = --size;
RunnableScheduledFuture<?> x = queue[s];
queue[s] = null;
if (s != 0)
siftDown(0, x);
setIndex(f, -1);
return f;
}

public RunnableScheduledFuture<?> poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
RunnableScheduledFuture<?> first = queue[0];
if (first == null || first.getDelay(NANOSECONDS) > 0)
return null;
else
return finishPoll(first);
} finally {
lock.unlock();
}
}

public RunnableScheduledFuture<?> take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (;;) {
RunnableScheduledFuture<?> first = queue[0];
if (first == null)
available.await();
else {
long delay = first.getDelay(NANOSECONDS);
if (delay <= 0)
return finishPoll(first);
first = null; // don't retain ref while waiting
if (leader != null)
available.await();
else {
Thread thisThread = Thread.currentThread();
leader = thisThread;
try {
available.awaitNanos(delay);
} finally {
if (leader == thisThread)
leader = null;
}
}
}
}
} finally {
if (leader == null && queue[0] != null)
available.signal();
lock.unlock();
}
}

public RunnableScheduledFuture<?> poll(long timeout, TimeUnit unit)
throws InterruptedException {
long nanos = unit.toNanos(timeout);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (;;) {
RunnableScheduledFuture<?> first = queue[0];
if (first == null) {
if (nanos <= 0)
return null;
else
nanos = available.awaitNanos(nanos);
} else {
long delay = first.getDelay(NANOSECONDS);
if (delay <= 0)
return finishPoll(first);
if (nanos <= 0)
return null;
first = null; // don't retain ref while waiting
if (nanos < delay || leader != null)
nanos = available.awaitNanos(nanos);
else {
Thread thisThread = Thread.currentThread();
leader = thisThread;
try {
long timeLeft = available.awaitNanos(delay);
nanos -= delay - timeLeft;
} finally {
if (leader == thisThread)
leader = null;
}
}
}
}
} finally {
if (leader == null && queue[0] != null)
available.signal();
lock.unlock();
}
}

public void clear() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
for (int i = 0; i < size; i++) {
RunnableScheduledFuture<?> t = queue[i];
if (t != null) {
queue[i] = null;
setIndex(t, -1);
}
}
size = 0;
} finally {
lock.unlock();
}
}

private RunnableScheduledFuture<?> peekExpired() {
// assert lock.isHeldByCurrentThread();
RunnableScheduledFuture<?> first = queue[0];
return (first == null || first.getDelay(NANOSECONDS) > 0) ?
null : first;
}

public int drainTo(Collection<? super Runnable> c) {
if (c == null)
throw new NullPointerException();
if (c == this)
throw new IllegalArgumentException();
final ReentrantLock lock = this.lock;
lock.lock();
try {
RunnableScheduledFuture<?> first;
int n = 0;
while ((first = peekExpired()) != null) {
c.add(first); // In this order, in case add() throws.
finishPoll(first);
++n;
}
return n;
} finally {
lock.unlock();
}
}

public int drainTo(Collection<? super Runnable> c, int maxElements) {
if (c == null)
throw new NullPointerException();
if (c == this)
throw new IllegalArgumentException();
if (maxElements <= 0)
return 0;
final ReentrantLock lock = this.lock;
lock.lock();
try {
RunnableScheduledFuture<?> first;
int n = 0;
while (n < maxElements && (first = peekExpired()) != null) {
c.add(first); // In this order, in case add() throws.
finishPoll(first);
++n;
}
return n;
} finally {
lock.unlock();
}
}

public Object[] toArray() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return Arrays.copyOf(queue, size, Object[].class);
} finally {
lock.unlock();
}
}

@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (a.length < size)
return (T[]) Arrays.copyOf(queue, size, a.getClass());
System.arraycopy(queue, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
} finally {
lock.unlock();
}
}

public Iterator<Runnable> iterator() {
return new Itr(Arrays.copyOf(queue, size));
}

private class Itr implements Iterator<Runnable> {
final RunnableScheduledFuture<?>[] array;
int cursor = 0; // index of next element to return
int lastRet = -1; // index of last element, or -1 if no such

Itr(RunnableScheduledFuture<?>[] array) {
this.array = array;
}

public boolean hasNext() {
return cursor < array.length;
}

public Runnable next() {
if (cursor >= array.length)
throw new NoSuchElementException();
lastRet = cursor;
return array[cursor++];
}

public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
DelayedWorkQueue.this.remove(array[lastRet]);
lastRet = -1;
}
}
}
}