優先順序佇列delayedworkqueue
delayedworkqueue用來存放將要執行的任務,其資料結構為有序二叉堆。
有序二叉堆的特點:
所有根結點必定不大於其兩個葉子節點
任意結點的子節點的索引位置是其本身索引位置乘2後+1
任意結點的父節點的索引位置是該結點的索引位置-1後除2並向下取整
當新新增元素時,加入到陣列的尾部,後面我們結合**分析新增過程delayedworkqueue按照任務超時時間公升序排序,原因是為了將即將要執行的任務放在盡量靠前的位置。下面分析新增操作:
public
boolean
offer
(runnable x)
else
if(queue[0]
== e)
}finally
return
true
;}
在呼叫此方法之前已經把任務封裝為runnablescheduledfuture型別,說白了其內部就是多了乙個執行時間,並且重寫了compareto方法。繼續看siftup()的實現,引數i為陣列的下標。
private
void
siftup
(int k, runnablescheduledfuture<
?> key)
queue[k]
= key;
setindex
(key, k)
;}
找到新元素的父節點,然後和父元素進行比較,如果新元素大於大於父節點(compareto)直接返回,否則和父元素進行交換。獲取元素有三種方式,poll()、take()、poll(long timeout, timeunit unit),分別為立即獲取、等待獲取、超時等待獲取。這裡主要分析等待獲取take方法。
public runnablescheduledfuture<
?>
take()
throws interruptedexception
finally}}
}}finally
}
注意一點leader變數表示正在獲取頭元素的執行緒,在**[1]處的判斷是什麼意思?假設佇列現在是空的,這是執行緒a進入,發現first為null會呼叫await方法,進入等待佇列。這是他會釋放鎖,有任務加入。就在此時執行緒b和執行緒a同時競爭鎖,但是執行緒b獲得了鎖,在**[2]處等待一定時間同時釋放鎖,但是執行緒a不一定會被喚醒,除非在b睡眠的時候有任務加入。很巧,此時執行緒a競爭到了鎖,來到[1]處,leader不為null,再次進入await。直到執行緒b執行完畢,呼叫了signal方法。
如果任務過期或者到達執行時間返回任務,並且重新組織二叉排序堆
private runnablescheduledfuture<
?>
finishpoll
(runnablescheduledfuture<
?> f)
private
void
siftdown
(int k, runnablescheduledfuture<
?> key)
queue[k]
= key;
// 將key賦值剛給右節點
setindex
(key, k)
;}
陣列的大小減1,獲取最後乙個節點同時置位null,呼叫siftdown方法,入參為0和最後乙個節點。
scheduledthreadpoolexecutor
scheduledthreadpoolexecutor 計畫任務執行緒池,這裡就不介紹他的具體使用方式了。其內部有兩個重要的內部類,delayedworkqueue和scheduledfuturetask。先看一下schedule方法。
public scheduledfuture<
?>
schedule
(runnable command,
long delay, timeunit unit)
schedule方法的作用是將定時任務封裝為runnablescheduledfuture型別,並新增值阻塞佇列中。至於何時呼叫,回想執行緒池中分析過,gettask方法:
private runnable gettask()
catch
(interruptedexception retry)
}
執行poll或者take時會阻塞到任務的執行時間。
總結:
計畫任務的延時和阻塞功能是在延時佇列中實現。
文中沒有詳細的描述scheduledfuturetask類,該類是對任務的封裝,並且scheduleatfixedrate的也是通過該類實現的,當任務執行完成之後,會再次新建乙個任務,加入到延時佇列中,這樣就可以重複的執行任務了。
系統的定時任務和延時任務
注 當任務有輸出時,輸出會以郵件的形式傳送給at任務的發起者。步驟 開啟postfix服務 命令 內部命令 1.輸入數字是檢視指定郵件的具體資訊 2.headers是檢視郵件列表 3.help檢視內部命令幫助 4.q是退出檢視郵件 命令 注 如果不寫username,預設在當前使用者執行命令 步驟 ...
Linux中的延時任務以及定時任務
root localhost at 23 37 設定任務執行時間 at rm fr mnt 任務執行動作 at ctrl d 用ctrl d發起任務 root localhost at now 1min 延時1分鐘 at rm fr mnt at 命令 注釋at l 檢視任務列表 at c 檢視任務...
Linux下的定時任務與延時任務
1 延時任務發起命令 at at 命令可以指定某一任務在將來的特定時間執行。該任務會在與shell會話斷開連線的情況下執行,用at命令將任務設定在一兩分鐘後執行時可以安全登出 at 命令必須指定任務應執行的時間。該指定可以是具體時間和日期,也可以是當前時間的相對時間 在鍵入 at 命令列之後 按 e...