Java執行緒(九):ScheduledExecutorService、ScheduledThreadPoolExecutor
ScheduledExecutorService
public interface ScheduledExecutorService extends ExecutorService
- 一個 ExecutorService,可安排在給定的延遲後執行或定期執行的命令。
- schedule 方法使用各種延遲建立任務,並返回一個可用於取消或檢查執行的任務物件。
- scheduleAtFixedRate 和 scheduleWithFixedDelay 方法建立並執行某些在取消前一直定期執行的任務。
- 用 Executor.execute(java.lang.Runnable) 和 ExecutorService 的 submit 方法所提交的命令,通過所請求的 0 延遲進行安排。schedule 方法中允許出現 0 和負數延遲(但不是週期),並將這些視為一種立即執行的請求。
方法摘要
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)
建立並執行在給定延遲後啟用的 ScheduledFuture。
ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit)
建立並執行在給定延遲後啟用的一次性操作。
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
建立並執行一個在給定初始延遲後首次啟用的定期操作,後續操作具有給定的週期;也就是將在 initialDelay 後開始執行,然後在 initialDelay+period 後執行,接著在 initialDelay + 2 * period 後執行,依此類推。
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
建立並執行一個在給定初始延遲後首次啟用的定期操作,隨後,在每一次執行終止和下一次執行開始之間都存在給定的延遲。
ScheduledThreadPoolExecutor
public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService
- 可另行安排在給定的延遲後執行命令,或者定期執行命令。
- 需要多個輔助執行緒時,或者要求 ThreadPoolExecutor 具有額外的靈活性或功能時,此類要優於 Timer。
- 一旦啟用已延遲的任務就執行它,但是有關何時啟用,啟用後何時執行則沒有任何實時保證。按照提交的先進先出 (FIFO) 順序來啟用那些被安排在同一執行時間的任務。
- 此類重寫 AbstractExecutorService 的 submit 方法,以生成內部物件控制每個任務的延遲和排程。
構造方法
ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler handler)
可以自定義corePoolSize、threadFactory、handler。
corePoolSize - 池中所儲存的執行緒數(包括空閒執行緒)
threadFactory - 執行程式建立新執行緒時使用的工廠,預設DefaultThreadFactory。
handler - 由於超出執行緒範圍和佇列容量而使執行被阻塞時所使用的處理程式,預設ThreadPoolExecutor.AbortPolicy。
ScheduledThreadPoolExecutor較ThreadPoolExecutor佇列的區別是:前者只能使用DelayedWorkQueue,後者可自定義BlockingQueue。
方法實現
Future submit(XX)
提交一個 Runnable 任務用於執行,並返回一個表示該任務的 Future。
// Override AbstractExecutorService methods
public Future<?> submit(Runnable task) {
return schedule(task, 0, TimeUnit.NANOSECONDS);
}
public <T> Future<T> submit(Runnable task, T result) {
return schedule(Executors.callable(task, result),
0, TimeUnit.NANOSECONDS);
}
public <T> Future<T> submit(Callable<T> task) {
return schedule(task, 0, TimeUnit.NANOSECONDS);
}
void execute(Runnable command)
使用所要求的零延遲執行命令。
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
schedule(command, 0, TimeUnit.NANOSECONDS);
}
從原始碼看出,submit和execute方法均由schedule(task, 0, TimeUnit.NANOSECONDS)來實現。
shutdown
在以前已提交任務的執行中發起一個有序的關閉,但是不接受新任務。
public void shutdown() {
cancelUnwantedTasks();
super.shutdown();
}
/**
* Cancels and clears the queue of all tasks that should not be run
* due to shutdown policy.
*/
private void cancelUnwantedTasks() {
boolean keepDelayed = getExecuteExistingDelayedTasksAfterShutdownPolicy();
boolean keepPeriodic = getContinueExistingPeriodicTasksAfterShutdownPolicy();
if (!keepDelayed && !keepPeriodic)
super.getQueue().clear();
else if (keepDelayed || keepPeriodic) {
Object[] entries = super.getQueue().toArray();
for (int i = 0; i < entries.length; ++i) {
Object e = entries[i];
if (e instanceof RunnableScheduledFuture) {
RunnableScheduledFuture<?> t = (RunnableScheduledFuture<?>)e;
if (t.isPeriodic()? !keepPeriodic : !keepDelayed)
t.cancel(false);
}
}
entries = null;
purge();
}
}
由原始碼看出,取消執行緒是利用Future.cancel特性,shutdown是呼叫的父類ThreadPoolExecutor.shutdown方法。
shutdownNow
嘗試停止所有正在執行的任務、暫停等待任務的處理,並返回等待執行的任務列表。
public List<Runnable> shutdownNow() {
return super.shutdownNow();//ThreadPoolExecutor.shutdownNow
}
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)
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;
}
schedule(Callable callable, long delay, TimeUnit unit)與其實現基本相同。
宣告RunnableScheduledFuture由其內部類ScheduledFutureTask實現。
延遲執行的核心實現
private void delayedExecute(Runnable command) {
if (isShutdown()) {
reject(command);//執行緒已關閉
return;
}
if (getPoolSize() < getCorePoolSize())//執行的執行緒小於核心執行緒,開啟新的執行緒
prestartCoreThread();
super.getQueue().add(command);
}
DelayedWorkQueue是ScheduledThreadPoolExecutor內部類,佇列的核心基於無界阻塞佇列DelayQueue實現。
private static class DelayedWorkQueue extends AbstractCollection<Runnable> implements BlockingQueue<Runnable> {
private final DelayQueue<RunnableScheduledFuture> dq = new DelayQueue<RunnableScheduledFuture>();
}
scheduleAtFixedRate
給定初始延遲後首次啟用的定期操作後,以initialDelay + N * period固定週期執行任務(N>=0)。
scheduleWithFixedDelay
給定初始延遲後首次啟用的定期操作後,每一次執行終止和下一次執行開始之間都存在給定的延遲delay。
通俗地理解scheduleAtFixedRate到了時間就自動執行,scheduleWithFixedDelay是每一次任務執行完成後,延遲delay時間,再執行一個任務。
第一種情況若任務執行時間長,任務有可能並行,而第二種只能序列。
ScheduledThreadPoolExecutor繼承ThreadPoolExecutor,只用了核心執行緒池,其任務佇列是採用了內部類DelayedWorkQueue實現, 任務實體由內部類ScheduledFutureTask實現,其實現compareTo方法,達到內部自然排序,具有延遲或定期執行任務的特性。
相關推薦
Java執行緒(九):ScheduledExecutorService、ScheduledThreadPoolExecutor
ScheduledExecutorService public interface ScheduledExecutorService extends ExecutorService 一個 ExecutorService,可安排在給定的延遲後執行或定
多執行緒(九): HashTable、HashMap和ConcurrentHashMap
public class HashTest { static Map<String, Integer> map = new HashMap<String, Integer>(); // static Map<String, Integer&g
Java執行緒(八):ThreadPoolExecutor、RejectedExecutionHandler
ThreadPoolExecutor public class ThreadPoolExecutor extends AbstractExecutorService 執行緒池可以解決兩個不同問題:由於減少了每個任務呼叫的開銷,它們通常可以在執行大量
Java執行緒(九):Condition-執行緒通訊更高效的方式
接近一週沒更新《Java執行緒》專欄了,主要是這周工作上比較忙,生活上也比較忙,呵呵,進入正題,上一篇講述了併發包下的Lock,Lock可以更好的解決執行緒同步問題,使之更面向物件,並且ReadWriteLock在處理同步時更強大,那麼同樣,執行緒間僅僅互斥是
Java執行緒(六):Executor、ExecutorService
Executor public interface Executor 執行已提交的 Runnable 任務的物件。 此介面提供一種將任務提交與每個任務將如何執行的機制(包括執行緒使用的細節、排程等)分離開來的方法。 記憶體一致性效果:執行緒中將 R
Java併發(十八):阻塞佇列BlockingQueue BlockingQueue(阻塞佇列)詳解 二叉堆(一)之 圖文解析 和 C語言的實現 多執行緒程式設計:阻塞、併發佇列的使用總結 Java併發程式設計:阻塞佇列 java阻塞佇列 BlockingQueue(阻塞佇列)詳解
阻塞佇列(BlockingQueue)是一個支援兩個附加操作的佇列。 這兩個附加的操作是:在佇列為空時,獲取元素的執行緒會等待佇列變為非空。當佇列滿時,儲存元素的執行緒會等待佇列可用。 阻塞佇列常用於生產者和消費者的場景,生產者是往佇列裡新增元素的執行緒,消費者是從佇列裡拿元素的執行緒。阻塞佇列就是生產者
Java多執行緒15:Queue、BlockingQueue以及利用BlockingQueue實現生產者/消費者模型
轉自:http://www.cnblogs.com/xrq730/p/4855857.htmlQueue是什麼佇列,是一種資料結構。除了優先順序佇列和LIFO佇列外,佇列都是以FIFO(先進先出)的方式對各個元素進行排序的。無論使用哪種排序方式,佇列的頭都是呼叫remove(
JAVA執行緒間協作wait、notify、notifyAll、sleep用途
在上節中,介紹了java多執行緒中同步鎖的概念,synchronized方法和synchronized程式碼塊都是為了解決執行緒併發的問題,同一時間允許一個執行緒訪問當前類或者物件。如果涉及到執行緒間的協作通訊,就需要用到wait、notify、notifyAll方法,這三個方法是Object的
Java執行緒池的認識、常用執行緒池的分析
什麼是程式,什麼是程序,什麼是執行緒,他們有什麼區別? 程式是指令和資料的有序集合,其本身並沒有任何執行的含義,是一個靜態的概念。 程序是一個動態的過程,是一個活動的實體。簡單來說,一個應用程式得到執行就可以看作是一個程序。程序可以包含多個同時執行的執行緒。程序也是擁有系統
Java執行緒池及Future、Callable獲得執行緒返回結果
Java執行緒池及Future、Callable獲得執行緒返回結果【Java執行緒池系列2】 Java多執行緒程式設計中,經常使用的Thread的Runnable()雖然被經常使用,但其有一個弊端,就是因為無法直接獲取該執行緒的返回值,因為Runnable內的run方法,
Java執行緒(十):ThreadPoolExecutor+BlockingQueue執行緒池示例
原始碼 首先定義擴充套件執行緒池ExtThreadPoolExecutor ExtThreadPoolExecutor作用是對執行緒池的增強,如在初始化執行緒池時、線上程執行前、執行後等處可新增自定義邏輯。 import java.util.con
Java執行緒(三):執行緒協作-生產者/消費者問題
上一篇講述了執行緒的互斥(同步),但是在很多情況下,僅僅同步是不夠的,還需要執行緒與執行緒協作(通訊),生產者/消費者問題是一個經典的執行緒同步以及通訊的案例。該問題描述了兩個共享固定大小緩衝區的執行緒,即所謂的“生產者”和“消費者”在實際執行時會發生的問題。
Java執行緒同步:synchronized鎖住的是程式碼還是物件
在Java中,synchronized關鍵字是用來控制執行緒同步的,就是在多執行緒的環境下,控制synchronized程式碼段不被多個執行緒同時執行。synchronized既可以加在一段程式碼上,也可以加在方法上。 關鍵是,不要認為給方法或者程式碼段加上synchron
Java執行緒休眠方法sleep、執行緒讓步yield和join方法
執行緒休眠(sleep方法) 執行緒休眠:讓執行緒暫緩執行,等到預計時間之後再恢復執行。 執行緒休眠會交出cpu,讓cpu去執行其他任務,但是不會釋放鎖。 比如:當前執行緒sleep休眠了,但是如果此執行緒在休眠前持有某個物件的鎖,那就算它休眠了其他執行緒也不能獲取到這個物件的鎖。
【Linux】執行緒總結:初識、建立、等待、終止、分離
學習環境 : Centos6.5 Linux 核心 2.6 Linux執行緒部分總結分為兩部分:(1)執行緒的使用 ,(2)執行緒的同步與互斥。 第一部分執行緒的使用主要介紹,執行緒的概念,建立執行緒,執行緒退出,以及執行緒的終止與分離。
Java執行緒(十三):BlockingQueue-執行緒的阻塞佇列
BlockingQueue作為執行緒容器,可以為執行緒同步提供有力的保障,其主要用到的方法包括: add(E o); //將指定的元素新增到此佇列中(如果立即可行),在成功時返回 true,其他情況則丟擲 IllegalStateException。 drainTo
Java執行緒(二):執行緒同步synchronized和volatile
上篇通過一個簡單的例子說明了執行緒安全與不安全,在例子中不安全的情況下輸出的結果恰好是逐個遞增的(其實是巧合,多執行幾次,會產生不同的輸出結果),為什麼會產生這樣的結果呢,因為建立的Count物件是執行緒共享的,一個執行緒改變了其成員變數num值,下一個執行緒
Java執行緒——Thread與Runnable、start()與run()
在java中可有兩種方式實現多執行緒,一種是繼承Thread類,一種是實現Runnable介面;Thread類是在java.lang包中定義的。一個類只要繼承了Thread類同時覆寫了本類中的run()方法就可以實現多執行緒操作了,但是一個類只能繼承一個父類,這是此方法的
Java執行緒(六):執行緒池
自JDK5之後,Java推出了一個併發包,java.util.concurrent,在Java開發中,我們接觸到了好多池的技術,String類的物件池、Integer的共享池、連線資料庫的連線池、Struts1.3的物件池等等,池的最終目的都是節約資源,以更小
uc筆記11---執行緒管理,執行緒函式:建立、等待、獲取、比較、終止、取消, 執行緒屬性
1. 基本概念 1)執行緒就是程式的執行路線,即程序內部的控制序列,或者說是程序的子任務。 2)執行緒,輕量級,不擁有自己獨立的記憶體資源,共享程序的程式碼區、資料區、堆區(注意沒有棧區)、 環境變數和命令列引數、檔案描述符、訊號處理函式、當前