簡體   English   中英

Java線程池:空閑線程會發生什么

[英]Java thread pool: What happens to idle threads

我試圖理解Java中的多線程。 我編寫了以下java程序來測試線程池。

public class ThreadPoolTest
{
    public static void main(String[] args)
    {
        ExecutorService executorService = Executors.newFixedThreadPool(5);

        for( int i = 0; i < 3; i++ )
        {
            executorService.submit(new Task(i+1));
        }
        executorService.shutdown();                     

    }

    public static class Task implements Runnable
    {
        private int taskId;

        public Task(int id)
        {
            taskId = id;
        }

        @Override
        public void run() {
            System.out.println("Executing task " + taskId + " performed by " + Thread.currentThread().getName() );
            try
            {
                Thread.sleep(3000);
            }
            catch(InterruptedException interruptEx)
            {
                System.out.println(Thread.currentThread().getName() + " got interrupted ");
            }
            System.out.println("Finished executing task " + taskId );
        }
    }
}

主線程創建執行器,創建5個線程,我只提交了3個任務。 之后我關閉了遺囑執行人。 當我運行代碼時,主線程在子線程之前完成。 在這種情況下,JVM是否負責子線程? 我還創建了一個包含5個線程的線程池,但只提交了3個任務。 當主線程退出時,剩余的2個線程是否會被終止?

執行程序服務關閉時實際發生了什么?

來自ExecutorService#shutdown()的文檔ExecutorService#shutdown()

啟動有序關閉,其中先前提交的任務將被執行,但不會接受任何新任務。

這意味着你提交給執行者的所有工作都將在他們自己的時間內完成,而不會中斷或“匆忙”他們,執行人員將正確完成工作線程,但服務也不接受新的工作,也不會立即終止。

比較ExecutorService#shutdownNow() ,它將嘗試盡快終止。

執行程序創建的Worker線程是內部類,它們具有對執行程序本身的引用。 (他們需要它能夠看到隊列,runstate等等!)運行線程不是垃圾收集的,所以當池中的每個線程都有該引用時,它們將使執行器保持活動狀態直到所有線程都死亡。 如果您不手動執行某些操作來停止線程,它們將永遠保持運行,您的JVM將永遠不會關閉。

如果5個線程只生成3個任務,則永遠不會啟動2個未使用的線程但是引用將保持不變,直到在finalize()中調用shutdown或所有活動線程完成執行。

以下是JAVA Docs的評論:

程序中不再引用且沒有剩余線程的池將自動>關閉。 如果您希望確保回收未引用的池>即使用戶忘記調用shutdown(),那么您必須通過設置適當的保持活動時間,使用零核心>線程的下限來安排未使用的線程>最終死亡和/或設置allowCoreThreadTimeOut(boolean)。

在這種情況下,JVM是否負責子線程?

操作系統管理線程並確定它們何時運行。

我還創建了一個包含5個線程的線程池,但只提交了3個任務。 當主線程退出時,剩余的2個線程是否會被終止?

不,線程一直運行,直到你關閉它們。

執行程序服務關閉時實際發生了什么?

線程被中斷,不會啟動任何新任務。 但是,如果您有一個忽略中斷的任務,它可以無限期地繼續運行。

當最后一個非deamon線程停止時,將觸發關閉鈎子(如果有)。

JVM是否負責子線程

JVM僅在完成所有守護程序線程后完成其執行。 如果您正在創建非守護進程,那么它將等待所有非守護進程線程完成。

當主線程退出時,剩余的2個線程是否會終止

線程將在按需模式下創建。 所以這里3個線程只創建了5個。

執行程序服務關閉時實際發生的情況

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.
This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM