添加元素,先添加到数组末尾,然后上调整堆。

取对首元素,把最后一个元素放到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源码的更多相关文章

  1. Java调度线程池ScheduledThreadPoolExecutor源码分析

    最近新接手的项目里大量使用了ScheduledThreadPoolExecutor类去执行一些定时任务,之前一直没有机会研究这个类的源码,这次趁着机会好好研读一下. 该类主要还是基于ThreadPoo ...

  2. ScheduledThreadPoolExecutor源码解读

    1. 背景 在之前的博文--ThreadPoolExecutor源码解读已经对ThreadPoolExecutor的实现原理与源码进行了分析.ScheduledExecutorService也是我们在 ...

  3. ScheduledThreadPoolExecutor源码分析-你知道定时线程池是如何实现延迟执行和周期执行的吗?

    Java版本:8u261. 1 简介 ScheduledThreadPoolExecutor即定时线程池,是用来执行延迟任务或周期性任务的.相比于Timer的单线程,定时线程池在遇到任务抛出异常的时候 ...

  4. Java并发包源码学习系列:线程池ScheduledThreadPoolExecutor源码解析

    目录 ScheduledThreadPoolExecutor概述 类图结构 ScheduledExecutorService ScheduledFutureTask FutureTask schedu ...

  5. ScheduledThreadPoolExecutor 源码分析

    ScheduledThreadPoolExecutor ScheduledThreadPoolExecutor 是能够在给定的延时之后.或周期性执行被提交任务的线程池 创建实例 /** * 线程池关闭 ...

  6. ScheduledThreadPoolExecutor源码主要部分解析

    ScheduledThreadPoolExecutor继承与基础线程池类ThreadPoolExecutor并实现ScheduledExecutorService接口. 其中ScheduledExec ...

  7. JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor

    JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor.它主要用来在 ...

  8. AQS源码深入分析之共享模式-你知道为什么AQS中要有PROPAGATE这个状态吗?

    本文基于JDK-8u261源码分析 本篇文章为AQS系列文的第二篇,前文请看:[传送门] 第一篇:AQS源码深入分析之独占模式-ReentrantLock锁特性详解 1 Semaphore概览 共享模 ...

  9. 并发编程(十五)——定时器 ScheduledThreadPoolExecutor 实现原理与源码深度解析

    在上一篇线程池的文章<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中从ThreadPoolExecutor源码分析了其运行机制.限于篇幅,留下了Scheduled ...

随机推荐

  1. Java中级知识归纳(四)

    十六.Java内存模型 特点:原子性.可见性.有序性. 原子性:read.load.use.store.write.synchronized关键字保证原子性 可见性:synchronized.vola ...

  2. Flask笔记:文件上传

    文件上传 enctype:在HTML中的form表单中form标签默认是`enctype="application/x-www-form-urlencoded"`,在文件上传时需要 ...

  3. jQuery 选择器有61种你都知道了多少

    下面列举了61种jQuery 选择器 参考 选择器 语句 描述 * $("*") 选择所有元素 #id $("#lastname") id=“lastname” ...

  4. webpack4 babel 篇

    demo 代码点此,如果对 babel 不熟,可以看一下babel 7 简单指北. webpack 使用 babel 来打包使用 es6 及以上语法的 js 文件是非常方便的,可以通过配置,将 es6 ...

  5. i春秋四周年庆典狂欢丨价值6000元的Web安全课程免费送啦

    重磅好消息 i春秋四周年庆典狂欢 感恩回馈新老用户 5888元的Web安全线上提高班 988元的Web安全线上入门班 免费送啦 快来围观 活动详情 1.活动时间:6月17日—6月30日 2.活动规则: ...

  6. 新手入门必看:VectorDraw 常见问题整理大全(二)

    VectorDraw Developer Framework(VDF)是一个用于应用程序可视化的图形引擎库.有了VDF提供的功能,您可以轻松地创建.编辑.管理.输出.输入和打印2D和3D图形文件.该库 ...

  7. web下载附件及修改名称

    /** * @param: url 附件地址 * @param: filename 下载后的文件名 */ function download(url, filename) { getBlob(url, ...

  8. Fundebug后端Node.js插件更新至0.2.0,支持监控Express慢请求

    摘要: 性能问题也是BUG,也需要监控. Fundebug后端Node.js异常监控服务 Fundebug是专业的应用异常监控平台,我们Node.js插件fundebug-nodejs可以提供全方位的 ...

  9. Spring Cloud Eureka详细说明

    之前学习了如何配置Eureka注册中心.消费者等,关于更详细的一些常用的配置在这里说明. 1.注册中心的自我保护模式 在我们调试Eureka的注册中心时,访问注册中心页面,常常会看见以下提示. 该提示 ...

  10. 多线程学习笔记(一) InvokeRequired 和 delegate

    入门示例: 假如有一个label,我们希望像走马灯一样,从1显示到100 private void button1_Click(object sender, EventArgs e) { ; i &l ...