[英]What is the order of execution for submitted task to the ExecutorService object?
向 ExecutorService 對象提交的任務的執行順序是什么?
場景:讓我們暫時假設 Executor 線程池大小為 5,我已經向它提交了 20 個可運行任務,我們知道一次只能執行 5 個任務,其余任務將在存儲桶中等待。 所以我的問題是提交的任務以什么順序執行。 它是遵循 FIFO 數據結構還是從桶中隨機選擇任務。
另外,有沒有辦法指定它應該以何種順序執行。
例子:
ExecutorService executor = Executors.newFixedThreadPool(5);
for(int i =0; i < 100; i++){
executor.submit(() -> {
System.out.println("print task");
})
}
它使用 LinkedBlockingQueue 來存儲掛起的任務。 因此,它遵循待處理任務的 FIFO 順序。 請查找 java 文檔以及方法簽名。
/**
* Creates a thread pool that reuses a fixed number of threads
* operating off a shared unbounded queue. At any point, at most
* {@code nThreads} threads will be active processing tasks.
* If additional tasks are submitted when all threads are active,
* they will wait in the queue until a thread is available.
* If any thread terminates due to a failure during execution
* prior to shutdown, a new one will take its place if needed to
* execute subsequent tasks. The threads in the pool will exist
* until it is explicitly {@link ExecutorService#shutdown shutdown}.
*
* @param nThreads the number of threads in the pool
* @return the newly created thread pool
* @throws IllegalArgumentException if {@code nThreads <= 0}
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
這取決於線程池和隊列的實現。
在 ThreadPoolExecutor 的情況下,隊列幾乎總是一個 SynchronousQueue、一個 LinkedBlockingQueue 或一個 ArrayBlockingQueue。 ArrayBlockingQueue 和 LinkedBlockingQueue 保證 FIFO 排序。 對於 SynchronousQueue,它取決於同步機制的 FIFO 能力,因為 SynchronousQueue 一次只能保留一個元素。 你最好假設它不能保證。
在 ScheduledThreadPoolExecutor 的情況下,隊列是一個 DelayQueue。 基本上它是一個優先級隊列,最有可能使用堆數據結構實現。 任務將按照延遲的順序從隊列中取出,但對於具有相同延遲的兩個任務,不能保證 FIFO。
但是,您必須考慮到,畢竟,鑒於線程的前置性質,從隊列中挑選任務並不意味着它會立即執行。 執行器的主循環基本上是這樣的:
public void run () {
while(!terminated) {
Runnable task = queue.take();
task.run();
}
}
考慮兩個線程正在運行此代碼。 這種情況可能會發生:
Runnable task = queue.take()
Runnable task = queue.take()
task.run();
task.run();
瞧,第二個任務排在隊列之后,但在第一個任務之前執行。 在實踐中,這種情況一直在發生。
最后,你不能也不應該假設任何事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.