第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時(shí)綁定郵箱和手機(jī)立即綁定

ScheduledThreadPoolExecutor

標(biāo)簽:
Java

ScheduledThreadPoolExecutor是java自带的用来设置延时任务的线程池,我们下来看看他是如何处理延时任务的。

public class ScheduledThreadPoolExecutor
        extends ThreadPoolExecutor
        implements ScheduledExecutorService 

他继承自ThreadPoolExecutor。所以总体的流程是和ThreadPoolExecutor一样的。有核心线程数,有队列,有最大线程数。
因为是延时或者定时任务。所以这些任务不会立马执行,所以在提交的流程上区别于ThreadPoolExecutor。

    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;
    }

第一步先转化成ScheduledFutureTask。

        private final long sequenceNumber;
        private long time;
        private final long period;
        RunnableScheduledFuture<V> outerTask = this;
        int heapIndex;

period是给定时任务记录的间隔。
time是算好的执行时间。
sequenceNumber是用来排序的,当执行的时间一样的,sequenceNumber小的会优先执行。
heapIndex是用来取消的索引。这个主要是用来取消任务的。
然后就把任务放在queue里,并且尝试增加线程池里的线程数。
在线程池启动线程后的流程是一样的。线程启动后会去从阻塞队列里获取任务。
ScheduledThreadPoolExecutor的阻塞队列是一个固定的类DelayedWorkQueue。
DelayedWorkQueue是一个优先队列的实现,这样就保证了第一个元素是最快需要执行的任务,就是我们上面ScheduledFutureTask的time和sequenceNumber。
这个队列的不同之处就在take等获取数据的时候,并不是里面就给数据,而是等待可以执行的时间后再给数据。

    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();
            }
        }

如果有第一个元素,就看是不是可执行,执行就是看记录的时间和当前时间对比,如果差值小于等于0就直接移动给线程执行。

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

如果不能执行,就先看leader是否存在,存在的话就直接await。这里的leader的作用是用来自我唤醒。leader线程的是awaitNanos。而不是直接await。这样就能保证总有一个线程在观察变化,当没有新增任务的时候,leader就会在awaitNanos之后,再次查看状态,此时原来的任务已经是可以执行的了,等待的时间到了。这里只要还有任务,就会去做 available.signal();因为这时候能执行的任务不止一个,再去唤醒一个线程。
如果中间新增了一个任务。在offer的时候会做一个判断

                if (queue[0] == e) {
                    leader = null;
                    available.signal();
                }

如果新增的一个是最小值。就会把leader设置为null,然后唤醒一个线程。这样被唤醒的线程,判断状态的时候,leader是null,他就会成为leader。这里设置了leader之后,可以减少很多无用的空转。
如果不设置,那么所有线程都会去记录自己等待的时间,其实执行的任务只有一个,其他的自动唤醒后都是空转一次。

Thread designated to wait for the task at the head of the queue. This variant of the Leader-Follower pattern (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to minimize unnecessary timed waiting. When a thread becomes the leader, it waits only for the next delay to elapse, but other threads await indefinitely. The leader thread must signal some other thread before returning from take() or poll(…), unless some other thread becomes leader in the interim. Whenever the head of the queue is replaced with a task with an earlier expiration time, the leader field is invalidated by being reset to null, and some waiting thread, but not necessarily the current leader, is signalled. So waiting threads must be prepared to acquire and lose leadership while waiting.

jdk的文档中详细的介绍了Leader-Follower模式的好处

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺得本文不錯(cuò),就分享一下吧!

評論

作者其他優(yōu)質(zhì)文章

正在加載中
JAVA開發(fā)工程師
手記
粉絲
1.6萬
獲贊與收藏
380

關(guān)注作者,訂閱最新文章

閱讀免費(fèi)教程

  • 推薦
  • 評論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評論
感謝您的支持,我會繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊有機(jī)會得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號

舉報(bào)

0/150
提交
取消