ScheduledThreadPoolExecutor源码
添加元素,先添加到数组末尾,然后上调整堆。
取对首元素,把最后一个元素放到0位置,然后下调整堆。
移除中间元素,把最后一个元素放到中间位置,然后下调整堆,下调整堆没动(已经是最大的),就在上调整堆。下调整堆动了,就不需要上调整堆。
//也是一个线程池ThreadPoolExecutor。里面的任务都是ScheduledFutureTask,队列是DelayedWorkQueue。
//线程池都是异步的,只不过FutureTask的run方法会把结果放到FutureTak里面去,然后通过这个返回的FutureTask获取执行结果。
//普通的Runnbale如果可以返回出去并且有返回值也可以获取结果。
//Periodic是周期任务。Delayed是一次性任务。
@SuppressWarnings("rawtypes")
public class ScheduledThreadPoolExecutor1 extends ThreadPoolExecutor1 implements ScheduledExecutorService {
//Shutdown之后,Periodic周期任务是否应该删除或者取消,还是继续执行。true继续,false不继续删除取消
private volatile boolean continueExistingPeriodicTasksAfterShutdown;
//Shutdown之后,DelayedT一次性任务是否应该删除或者取消,还是继续执行。true继续,false不继续删除取消
private volatile boolean executeExistingDelayedTasksAfterShutdown = false; //ScheduledFutureTask的cancel()方法用到。FutureTask任务被取消后(FutureTask.cancel()调用),是不是应该从队列删除。
private volatile boolean removeOnCancel = false; //序列号中断调度关系,进而保证绑定条目之间的FIFO顺序。
private static final AtomicLong sequencer = new AtomicLong(); final long now() {
return System.nanoTime();
} //给线程池设置参数
public ScheduledThreadPoolExecutor1(int corePoolSize) {//线程池的队列是DelayedWorkQueue
super(corePoolSize, Integer.MAX_VALUE, , NANOSECONDS, new DelayedWorkQueue());
}
//给线程池设置参数。线程池的队列是DelayedWorkQueue
public ScheduledThreadPoolExecutor1(int corePoolSize, ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, , NANOSECONDS, new DelayedWorkQueue(), threadFactory);
}
//给线程池设置参数。线程池的队列是DelayedWorkQueue
public ScheduledThreadPoolExecutor1(int corePoolSize, RejectedExecutionHandler1 handler) {
super(corePoolSize, Integer.MAX_VALUE, , NANOSECONDS, new DelayedWorkQueue(), handler);
}
//给线程池设置参数。线程池的队列是DelayedWorkQueue
public ScheduledThreadPoolExecutor1(int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler1 handler) {
super(corePoolSize, Integer.MAX_VALUE, , NANOSECONDS, new DelayedWorkQueue(), threadFactory, handler);
} //周期任务periodic=true,一次性任务periodic=false
boolean canRunInCurrentRunState(boolean periodic) {
//周期任务:RUNNING返回true,SHUTDOWN看continueExistingPeriodic,true就true false就fasle。不是RUNNING不是SHUTDOWN返回false
//一次性任务:RUNNING返回true,SHUTDOWN看executeExistingDelayed,true就true false就false。不是RUNNING不是SHUTDOWN返回false
return isRunningOrShutdown(periodic ? continueExistingPeriodicTasksAfterShutdown:executeExistingDelayedTasksAfterShutdown);
} //延迟或周期性执行任务。
//与ThreadPoolExecutor不同,这里直接把任务加入延迟队列。没有像ThreadPoolExecutor一样,woker满了才放入队列
private void delayedExecute(RunnableScheduledFuture<?> task) {//ScheduledFutureTask
if (isShutdown())
reject(task);
else {
//此时线程池的Worker线程还没有创建,因为任务是延迟执行,到时候在创建线程池线程。现在只是丢到队列里面去。
super.getQueue().add(task);
//进到canRunInCurrentRunState说明ctl>=SHUTDOWN,
//continueExistingPeriodic|executeExistingDelayed是true,不删除任务,
//继续开线程执行或者已经有足够的线程了丢到队列里面去让线程去执行,
//continueExistingPeriodic|executeExistingDelayed是false,删除任务
//ctl>SHUTDOWN,删除任务
if (isShutdown() && !canRunInCurrentRunState(task.isPeriodic()) && remove(task))
//从队列移除任务成功,FutureTask.cancel()
task.cancel(false);
else
//Worker线程数量<corePoolSize新建一个线程,大于corePoolSize不新建线程直接返回。
//开了一个Worker线程(初始任务是null),这个线程返回。一直会开到corePoolSize个线程就不开了。
ensurePrestart();
}
} //周期性任务, 把任务再次加到队列,并且又开一个线程
void reExecutePeriodic(RunnableScheduledFuture<?> task) {
//RUNNING返回true,SHUTDOWN看continueExistingPeriodic|continueExistingPeriodic。
//不是RUNNING不是SHUTDOWN返回false
if (canRunInCurrentRunState(true)) {
super.getQueue().add(task);//又加入到队列
//continueExistingPeriodic是true不删除任务,continueExistingPeriodic是false就删除任务,
//不是RUNNING不是SHUTDOWN删除任务。
if (!canRunInCurrentRunState(true) && remove(task))
task.cancel(false);
else
ensurePrestart();//又开线程去执行队列
}
}
//关闭线程池的回调
public void onShutdown() {
BlockingQueue<Runnable> q = super.getQueue();
boolean keepDelayed = getExecuteExistingDelayedTasksAfterShutdownPolicy();
boolean keepPeriodic = getContinueExistingPeriodicTasksAfterShutdownPolicy();
if (!keepDelayed && !keepPeriodic) {//keepDelayed=keepPeriodic=false
for (Object e : q.toArray())
if (e instanceof RunnableScheduledFuture<?>)
((RunnableScheduledFuture<?>) e).cancel(false);//队列的每个任务都取消.FutureTask.cancel()
q.clear();
} else {//keepDelayed keepPeriodic有一个为true
for (Object e : q.toArray()) {
if (e instanceof RunnableScheduledFuture) {
RunnableScheduledFuture<?> t = (RunnableScheduledFuture<?>) e;
//true||:周期任务,keepPeriodic=fasle,shutdown之后停止任务。一次性任务,keepDelaye=fasle,shutdown之后停止任务。
//:删除取消任务。
//false||true:周期任务|一次性任务,shutdown之后继续任务,但是FutureTask任务已经被cancel(true|fasle)取消了。
//:删除取消任务。
if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) || t.isCancelled()) {
if (q.remove(t))
t.cancel(false);//FutureTask.cancel()
}
//fasle||fasle:周期任务|一次性任务,shutdown之后继续任务,并且FutureTask任务没有被cancel(true|fasle)取消。
//:不移除不取消任务。
}
}
}
tryTerminate();//尝试终止线程池
} //默认实现只返回给定的任务。
//然后在调用decorateTask进行包装,该方法是留给用户去扩展的,默认是个空方法
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;
} private long triggerTime(long delay, TimeUnit unit) {
return triggerTime(unit.toNanos((delay < ) ? : delay));
} long triggerTime(long delay) {
return now() + ((delay < (Long.MAX_VALUE >> )) ? delay : overflowFree(delay));
} private long overflowFree(long delay) {
Delayed head = (Delayed) super.getQueue().peek();
if (head != null) {
long headDelay = head.getDelay(NANOSECONDS);
if (headDelay < && (delay - headDelay < ))
delay = Long.MAX_VALUE + headDelay;
}
return delay;
}
//延期执行,异步
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
if (command == null || unit == null) throw new NullPointerException();
//Runnable封装成ScheduledFutureTask,返回这个ScheduledFutureTask
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();
//封装任务ScheduledFutureTask
RunnableScheduledFuture<V> t = decorateTask(callable,new ScheduledFutureTask<V>(callable, triggerTime(delay, unit)));
delayedExecute(t);//加入队列开线程
return t;
}
//周期执行。initialDelay延迟多次时间开始执行,period每多次时间执行一次。
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
if (period <= ) throw new IllegalArgumentException();
ScheduledFutureTask<Void> sft = new ScheduledFutureTask<Void>(command, null, triggerTime(initialDelay, unit),unit.toNanos(period));//任务封装成ScheduledFutureTask
RunnableScheduledFuture<Void> t = decorateTask(command, sft);//返回t=sft
sft.outerTask = t;//outerTask=自己
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 <= ) 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, , NANOSECONDS);
} // Override AbstractExecutorService methods
public Future<?> submit(Runnable task) {
return schedule(task, , NANOSECONDS);
} public <T> Future<T> submit(Runnable task, T result) {
return schedule(Executors1.callable(task, result), , NANOSECONDS);
} public <T> Future<T> submit(Callable<T> task) {
return schedule(task, , NANOSECONDS);
} public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) {
continueExistingPeriodicTasksAfterShutdown = value;
//true&&true:shutdown之后不继续周期任务,ctl>=SHUTDWON:取消队列中所有的任务
if (!value && isShutdown())
onShutdown();
//fasle:shutdown之后继续周期任务:不停止队列的任务
//true&&false:shutdown之后不继续周期任务,ctl线程池正常状态:不停止队列的任务
} public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() {
return continueExistingPeriodicTasksAfterShutdown;
} public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) {
executeExistingDelayedTasksAfterShutdown = value;
//true&&true:shutdown之后不继续一次性任务,ctl>=SHUTDWON:取消队列中所有的任务
if (!value && isShutdown())
onShutdown();
//fasle:shutdown之后继续周期任务:不停止队列的任务
//true&&false:shutdown之后不继续周期任务,ctl线程池正常状态:不停止队列的任务
} public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() {
return executeExistingDelayedTasksAfterShutdown;
} //取消任务时是否应立即从work queue工作队列中删除的策略。该值默认为假。ScheduledFutureTask的cancel()方法用到。
//FutureTask任务被取消后(FutureTask.cancel()调用),是不是应该从队列删除。
public void setRemoveOnCancelPolicy(boolean value) {
removeOnCancel = value;
} public boolean getRemoveOnCancelPolicy() {//ScheduledFutureTask的cancel()方法用到。
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 = ;
//ScheduledFutureTask数组,是一个数组,堆排序的数组,里面的任务是ScheduledFutureTask
private RunnableScheduledFuture<?>[] queue = new RunnableScheduledFuture<?>[INITIAL_CAPACITY];
private final ReentrantLock lock = new ReentrantLock();//任务入队的锁
private int size = ; //当该任务到触发时间时,会唤醒很多woker线程,这显然是没有必要的。
private Thread leader = null;//取队列任务的worker线程。 private final Condition available = lock.newCondition(); //如果是scheduledfuturetask,则设置f的heapIndex。
private void setIndex(RunnableScheduledFuture<?> f, int idx) {
if (f instanceof ScheduledFutureTask)
((ScheduledFutureTask) f).heapIndex = idx;
} private void siftUp(int k, RunnableScheduledFuture<?> key) {//key打算放到k位置
while (k > ) {
int parent = (k - ) >>> ;//父节点位置
RunnableScheduledFuture<?> e = queue[parent];
if (key.compareTo(e) >= )//key大于父节点不交换,比较的是time,
break;
//小于等于父节点
queue[k] = e;//父节点放到k的位置
setIndex(e, k);//设置父节点索引为k
k = parent;//准备放到parent位置再比较
}
queue[k] = key;//key放到k位置
setIndex(key, k);//设置key的堆索引=k
} private void siftDown(int k, RunnableScheduledFuture<?> key) {
int half = size >>> ;
while (k < half) {
int child = (k << ) + ;
RunnableScheduledFuture<?> c = queue[child];
int right = child + ;
if (right < size && c.compareTo(queue[right]) > )
c = queue[child = right];
if (key.compareTo(c) <= )
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.5倍oldCapacity
if (newCapacity < ) // 溢出了
newCapacity = Integer.MAX_VALUE;//DelayedWorkQueue堵塞队列是无限大的,几乎为无上限。所以,不存在最大线程数
//这里没有向用户开放maximumPoolSize的设置,原因是DelayedWorkQueue中的元素在大于初始容量16时,会进行扩容,也就是说队列不会装满,maximumPoolSize参数即使设置了也不会生效。
queue = Arrays.copyOf(queue, newCapacity);
} //查找给定对象的索引,如果不存在则为-1。
private int indexOf(Object x) {
if (x != null) {
if (x instanceof ScheduledFutureTask) {
int i = ((ScheduledFutureTask) x).heapIndex;
if (i >= && i < size && queue[i] == x)
return i;
} else {//没有heapIndex属性
for (int i = ; i < size; i++)
if (x.equals(queue[i]))
return i;
}
}
return -;
} public boolean contains(Object x) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return indexOf(x) != -;
} finally {
lock.unlock();
}
} public boolean remove(Object x) {
final ReentrantLock lock = this.lock;//其余线程不能操作队列
lock.lock();
try {
int i = indexOf(x);
if (i < )
return false; setIndex(queue[i], -);
int s = --size;
RunnableScheduledFuture<?> replacement = queue[s];
queue[s] = null;
if (s != i) {
siftDown(i, replacement);//数组最后一个元素准备放到i位置,下调整堆
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() == ;
} public int remainingCapacity() {
return Integer.MAX_VALUE;
} public RunnableScheduledFuture<?> peek() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return queue[];
} finally {
lock.unlock();
}
} public boolean offer(Runnable x) {//ScheduledFutureTask
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)//大于16就扩容
grow();
size = i + ;
if (i == ) {
queue[] = e;
setIndex(e, );//设置堆索引
} else {//i>=1
//把任务加入堆中,并调整堆结构,这里就会根据任务的触发时间排列
//把需要最早执行的任务放在前面
siftUp(i, e);//准备在数组最后位置插入e,根据time调整堆
}
//如果新加入的元素就是队列头,这里有两种情况
//1.这是用户提交的第一个任务
//2.新任务进行堆调整以后,排在队列头(原来在最末尾,现在调整到第一个了)
if (queue[] == e) {//添加的任务是第一个
leader = null;//
available.signal();//唤醒取队列的worker线程
}
} 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 != )//s=0只有一个元素
siftDown(, x);//最后一个元素拿出来,准备放到0位置,然后调整堆。
setIndex(f, -);//设置任务的堆索引=-1就是数组的位置,
return f;
} public RunnableScheduledFuture<?> poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
RunnableScheduledFuture<?> first = queue[];
if (first == null || first.getDelay(NANOSECONDS) > )
return null;
else
return finishPoll(first);
} finally {
lock.unlock();
}
}
//线程池的Worek线程从队列中取任务,多线程访问。可以根据元素的过期时间来对元素进行排列,因此,先过期的元素会在队首,每次从队列里取出来都是最先要过期的元素。
public RunnableScheduledFuture<?> take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (;;) {
//列头的元素是最先“到期”的元素,每次取的是queue[0],如果队列里面没有元素到期,是不能从列头获取元素的,哪怕有元素也不行。也就是说只有在延迟期到时才能够从队列中取元素。
RunnableScheduledFuture<?> first = queue[];
if (first == null)
//如果队列为空,则阻塞等待加入元素时唤醒
//线程池中的worker线程从队列获取任务去执行:workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take(),没有任务这个线程池线程就阻塞在这里。
available.await();
else {
long delay = first.getDelay(NANOSECONDS);//判断还剩下多少时间
if (delay <= )
return finishPoll(first);//成功获得任务
first = null; // don't retain ref while waiting
//这里表示该任务已经分配给了其他线程,当前线程等待唤醒就可以
if (leader != null)//让leader去取
available.await();//不是leader的线程是死等,而不是等待多长时间,只有leader是等待多长时间。worker取任务线程。
else {
//否则把给任务分配给当前线程
Thread thisThread = Thread.currentThread();
leader = thisThread;
try {
//leader线程在这里等待,第一个阻塞等待的线程,第一个取的线程。一定要leader线程唤醒后去取,其他线程才能去取,然后成为新的leader。
available.awaitNanos(delay);//Worker线程取任务阻塞
} finally {
if (leader == thisThread)
leader = null;
}
}
}
}
} finally {
if (leader == null && queue[] != null)
available.signal();//Worker线程取任务唤醒
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[];
if (first == null) {
if (nanos <= )
return null;
else
nanos = available.awaitNanos(nanos);
} else {
long delay = first.getDelay(NANOSECONDS);
if (delay <= )
return finishPoll(first);
if (nanos <= )
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[] != null)
available.signal();
lock.unlock();
}
} public void clear() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
for (int i = ; i < size; i++) {
RunnableScheduledFuture<?> t = queue[i];
if (t != null) {
queue[i] = null;
setIndex(t, -);
}
}
size = ;
} finally {
lock.unlock();
}
} private RunnableScheduledFuture<?> peekExpired() {
// assert lock.isHeldByCurrentThread();
RunnableScheduledFuture<?> first = queue[];
return (first == null || first.getDelay(NANOSECONDS) > ) ? 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 = ;
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 <= )
return ;
final ReentrantLock lock = this.lock;
lock.lock();
try {
RunnableScheduledFuture<?> first;
int n = ;
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, , a, , 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 = ;
int lastRet = -; 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 < )
throw new IllegalStateException();
DelayedWorkQueue.this.remove(array[lastRet]);
lastRet = -;
}
}
} //是一个可以把结果放在outcome的FutureTask,通过FutureTask的outcome返回结果。
public class ScheduledFutureTask<V> extends FutureTask1<V> implements RunnableScheduledFuture<V> {
//数组的下边位置,-1表示不再数组里面了
int heapIndex;
//给ScheduledThreadPoolExecutor池子中添加的任务的序号,从0开始加1,
private final long sequenceNumber; private long time;//延迟多次时间开始执行, //以纳秒为单位的重复任务周期。
//正值表示固定速率执行。
//负值表示固定延迟执行。
//值0表示非重复任务。
private final long period;//每多次时间执行一次。 //由ReexecutePeriodic重新排队的实际任务
RunnableScheduledFuture<V> outerTask = this;//ScheduledFutureTask ScheduledFutureTask(Runnable r, V result, long ns) {
super(r, result);//设置FutureTask的callable和state。任务是封装在了ScheduledFutureTask的父类FutureTask中了,
this.time = ns;//延迟多次时间开始执行,
this.period = ;//每0时间执行一次。一次性任务
this.sequenceNumber = sequencer.getAndIncrement();
} ScheduledFutureTask(Runnable r, V result, long ns, long period) {
super(r, result);//设置FutureTask的callable和state。
this.time = ns;//延迟多次时间开始执行,
this.period = period;//每多次时间执行一次。
this.sequenceNumber = sequencer.getAndIncrement();//给ScheduledThreadPoolExecutor池子中添加的任务的序号
} ScheduledFutureTask(Callable<V> callable, long ns) {
super(callable);//设置FutureTask的callable和state。
this.time = ns;
this.period = ;//每0时间执行一次。一次性任务
this.sequenceNumber = sequencer.getAndIncrement();//给ScheduledThreadPoolExecutor池子中添加的任务的序号,sequencer加1,sequenceNumber还是加1之前的值。
} public long getDelay(TimeUnit unit) {//距离下次任务执行时间的时间间隔;
return unit.convert(time - now(), NANOSECONDS);
} //小于0自己小,大于0自己大,等于0相等
public int compareTo(Delayed other) {//用于比较任务之间的优先级关系,如果距离下次执行的时间间隔较短,则优先级高;
if (other == this) // 同一个对象返回0
return ;
if (other instanceof ScheduledFutureTask) {
ScheduledFutureTask<?> x = (ScheduledFutureTask<?>) other;
long diff = time - x.time;
if (diff < )//自己小
return -;
else if (diff > )//自己大
return ;
//时间相等,看sequenceNumber序列号
else if (sequenceNumber < x.sequenceNumber)
return -;//自己小
else
return ;//自己大
}
long diff = getDelay(NANOSECONDS) - other.getDelay(NANOSECONDS);
return (diff < ) ? - : (diff > ) ? : ;
} //这是一个周期性的(不是一次性的)动作。period=0一次性。period
public boolean isPeriodic() {
return period != ;
} //设置下次运行定期任务的时间。每5秒执行一次,period=5,下一次执行时间=time+5
//scheduleAtFixedRate会执行到情况一,下一次任务的启动时间最早为上一次任务的启动时间加period。
//scheduleWithFixedDelay会执行到情况二,这里很巧妙的将period参数设置为负数到达这段代码块,在此又将负的period转为正数。情况二将下一次任务的启动时间设置为当前时间加period。
private void setNextRunTime() {
long p = period;
if (p > )
time += p;
//scheduleAtFixedRate方法提交任务时,任务后续执行的延迟时间都已经确定好了,分别是initialDelay,initialDelay + period,initialDelay + 2 * period以此类推。
else
//scheduleWithFixedDelay方法提交任务时,第一次执行的延迟时间为initialDelay,后面的每次执行时间都是在前一次任务执行完成以后的时间点上面加上period延迟执行。
time = triggerTime(-p);
} //1.添加任务到队列之后,线程池处于关闭状态,移除任务成功后,就去取消任务。
public boolean cancel(boolean mayInterruptIfRunning) {
boolean cancelled = super.cancel(mayInterruptIfRunning);
if (cancelled && removeOnCancel && heapIndex >= )//heapIndex >= 0这个任务还在数组里面
remove(this);
return cancelled;
} //线程池里面task.run()就是ScheduledFutureTask.run,转而super就是FutureTask.run,就是真正Runnable.run
public void run() {
boolean periodic = isPeriodic();
if (!canRunInCurrentRunState(periodic))
cancel(false);
else if (!periodic)//不是周期的
ScheduledFutureTask.super.run();//真正Runnable.run
else if (ScheduledFutureTask.super.runAndReset()) {//是周期的,runAndReset没有设置返回值
setNextRunTime();
reExecutePeriodic(outerTask);//outerTask是任务自己。又把任务加到队列,如果线程池中worker线程数<corepooolsize,就又开一个线程池线程。注意:这个新开的线程池线程,是调用task.run()就是ScheduledFutureTask.run的线程池线程开的。
}
}
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) throws Exception {
// 创建corepoolSize=2的线程池
ScheduledExecutorService scheduledThreadPool = Executors1.newScheduledThreadPool(); new Thread(new Runnable() {
@Override
public void run() {
scheduledThreadPool.shutdown();
}
}).start(); FutureTask1 t1 = (ScheduledFutureTask) scheduledThreadPool.schedule( new Callable<String>() {
@Override
public String call() throws Exception {
return "Callable1" ;
}
}, , TimeUnit.SECONDS);//返回将Callable封装的FutureTask t1.get();//从FutureTask获取结果
t1.cancel(true);//从FutureTask取消任务 // 10秒后执行,周期性执行,每5秒执行一次
FutureTask1 t3 = (FutureTask1) scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("Runnable");
} }, , , TimeUnit.SECONDS);
t3.get();//获取不到结果,一直卡住 // 10秒后执行,一次性任务
FutureTask1 t4 = (FutureTask1) scheduledThreadPool.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
System.out.println("Runnable");
} }, , , TimeUnit.SECONDS);
t4.get(); scheduledThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println("Runnable");
} });
scheduledThreadPool.submit(new Runnable() {
@Override
public void run() {
System.out.println("Runnable");
} });
scheduledThreadPool.submit(new Runnable() {
@Override
public void run() {
System.out.println("Runnable");
} }, "期望值");
scheduledThreadPool.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "Callable";
}
});
}
}
ScheduledThreadPoolExecutor源码的更多相关文章
- Java调度线程池ScheduledThreadPoolExecutor源码分析
最近新接手的项目里大量使用了ScheduledThreadPoolExecutor类去执行一些定时任务,之前一直没有机会研究这个类的源码,这次趁着机会好好研读一下. 该类主要还是基于ThreadPoo ...
- ScheduledThreadPoolExecutor源码解读
1. 背景 在之前的博文--ThreadPoolExecutor源码解读已经对ThreadPoolExecutor的实现原理与源码进行了分析.ScheduledExecutorService也是我们在 ...
- ScheduledThreadPoolExecutor源码分析-你知道定时线程池是如何实现延迟执行和周期执行的吗?
Java版本:8u261. 1 简介 ScheduledThreadPoolExecutor即定时线程池,是用来执行延迟任务或周期性任务的.相比于Timer的单线程,定时线程池在遇到任务抛出异常的时候 ...
- Java并发包源码学习系列:线程池ScheduledThreadPoolExecutor源码解析
目录 ScheduledThreadPoolExecutor概述 类图结构 ScheduledExecutorService ScheduledFutureTask FutureTask schedu ...
- ScheduledThreadPoolExecutor 源码分析
ScheduledThreadPoolExecutor ScheduledThreadPoolExecutor 是能够在给定的延时之后.或周期性执行被提交任务的线程池 创建实例 /** * 线程池关闭 ...
- ScheduledThreadPoolExecutor源码主要部分解析
ScheduledThreadPoolExecutor继承与基础线程池类ThreadPoolExecutor并实现ScheduledExecutorService接口. 其中ScheduledExec ...
- JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor
JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor.它主要用来在 ...
- AQS源码深入分析之共享模式-你知道为什么AQS中要有PROPAGATE这个状态吗?
本文基于JDK-8u261源码分析 本篇文章为AQS系列文的第二篇,前文请看:[传送门] 第一篇:AQS源码深入分析之独占模式-ReentrantLock锁特性详解 1 Semaphore概览 共享模 ...
- 并发编程(十五)——定时器 ScheduledThreadPoolExecutor 实现原理与源码深度解析
在上一篇线程池的文章<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中从ThreadPoolExecutor源码分析了其运行机制.限于篇幅,留下了Scheduled ...
随机推荐
- RSA加密方法
/// <summary> /// RSA加密 /// </summary> /// <param name="dat ...
- Python【day 13】内置函数01
1.python3.6.2 一共有 68个内置函数2.分成6个大类 1.反射相关-4个 2.面向对象相关-9个 3.作用域相关--2个 1.globlas() #注意:最后是s,复数形式 查看全局作用 ...
- Eureka自我保护机制源码解析
默认情况下,当EurekaServer在一定时间内(默认90秒)没有接收到某个客户端实例的心跳,EurekaServer将会注销该实例.但是当网络分区故障发生时,客户端与EurekaServer之间无 ...
- 第九届极客大挑战——怎么又是江师傅的秘密(java反序列化)
这道题其实是考jsp和java的,我没学过jsp,java倒是有一点了解,但是刚拿到题的时候还是看不懂java代码里的内容,所以去简单学习了下jsp(jsp教程),按照教程里的步骤搭建了eclipse ...
- android studio学习----常用快捷键
Action Mac OSX Win/Linux 注释代码(//) Cmd + / Ctrl + / 注释代码(/**/) Cmd + Option + / Ctrl + Shift + / 格式化代 ...
- Scrum 冲刺第四篇
我们是这次稳了队,队员分别是温治乾.莫少政.黄思扬.余泽端.江海灵 一.会议 1.1 28号站立式会议照片: 1.2 昨天已完成的事情 团队成员 昨日已完成的任务 黄思扬 活动内容管理页(前端) ...
- Python实现MQTT接收订阅数据
一.背景 目前MQTT的标准组织官网:http://www.mqtt.org,里面列出了很多支持的软件相关资源. 一个轻量级的MQTT服务器是:http://www.mosquitto.org,可以运 ...
- Python列表操作与深浅拷贝(7)——列表深浅拷贝、删除、反转、排序
列表复制 浅拷贝:简单类型元素全复制,引用类型元素只复制引用 L1 = [3,2,1,[4,5,6],8,'abc'] L1 [3, 2, 1, [4, 5, 6], 8, 'abc'] L2 = L ...
- c# 第三节 vs的安装
本节内容: 学会安装vs 一:下载 地址:http://down.lansedongli.com/view/30323.html 二.vs2015支持的操作系统 三.vs2015的硬件要求 四.安装 ...
- python函数中的不定长参数
python自定义函数中有两中不定长参数,第一种是*name,第二种是**name.加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数.加了两个星号 ** 的参数会以字典的 ...