2015-06-20 147 views
0

在Java庫線程池實現,通常關停池是指:停止在自定義線程池中的所有線程(如關閉)

- 停止受理執行

新任務

-previously提交的任務

- 所有池中的線程終止

關於最後一點,你將如何停止池中的線程可能嘗試採取新的任務,之後已被停止?

我的線程做這樣的事情(在Java僞代碼):

public void run() { 
    while(!isStopped) { 
    Task task = taskQueue.take(); //line1 
    task.run(); //line2 
    } 
} 

,並有一個方法停止:

public synchronized void stop(){ 
    isStopped = true; 
    this.interrupt(); 
} 

在我的線程池類,我有一個方法停止:

public synchronized void shutdown(){ 
    this.isShutdown = true; //to stop the whole pool 
    for(PoolThread thread : threads) 
    thread.stop(); 
} 

的一點是,如果一個線程到達線1,isStopped是假的,但在第同時它可以被泳池類設置爲真。我怎麼記得我應該再次停止線程?調用中斷是否足夠?

回答

1

通過任務隊列發送關閉消息:

static Task stop = // some special value 

public void run() { 
    while (true) { 
    Task task = taskQueue.take(); 
    if (task == stop) { 
     break; 
    } 
    task.run(); 
    } 
} 

shutDown

public synchronized void shutdown(){ 
    if (isShutdown) { 
    return; 
    } 
    this.isShutdown = true; 
    for(PoolThread thread : threads) { 
    taskQueue.put(PoolThread.stop); 
    } 
} 

與隊列等於線程的數量,一旦所有的一些停產的消息工作完成後,線程將分別接收關閉消息並關閉。 (請注意,我們並不需要關心哪個線程獲取其關閉消息。)

+0

感謝。我喜歡這個解決方案。關於shutdownNow怎麼樣?這就像關機,但只有已經執行任務的線程可以終止他們的工作。沒有新任務可以添加到隊列中。也許,這足以清空隊列(同步)並重用這個相同的想法?我認爲它可以工作。你說什麼?當然,如果一個線程花了很長時間來完成一個任務,這將阻止整個關閉(但如果我沒有弄錯,這對java庫線程池也是如此)。 – Kami

+1

如果得到一個關機消息線程終止自己之前它重新排隊,需要任意數量的線程池只有一個關閉消息。 –

+0

@Kami:對於'shutdownNow'是,你要排在隊列和中斷線程,以及發送關閉消息。 – user2357112