Java多執行緒設計模式(6)兩階段終止模式

科技小能手發表於2017-11-12

一 Two-Phase Termination Pattern

  Two-Phase Termination Pattern,指的就是當希望結束一個執行緒的時候,送出一個終止請求,但是不會馬上停止,做一些重新整理工作。進入“終止處理中”,在該狀態下,不會進行該執行緒日常工作任務的操作,而是進行一些終止操作。

   這個方式所考慮的因素如下

  1,必須要考慮到使得該執行緒能夠安全的結束,Thread中的stop會有問題的,因為它會不管執行緒執行到哪裡,都會馬上停止,不能保證安全的結束。

  2,一定能夠進行正常的終止處理,在java中,這點可以使用finally來實現

  3,能夠高響應的終止,收到終止後,當執行緒在wait或者sleep或者join的時候,不用等到時間到才終止,而是馬上中斷執行緒的這些狀態,進而進行終止操作。

   當一個執行緒正在執行週期性的工作時候,在“作業中”發了停止執行緒的請求,此時該執行緒不能馬上離開停止,而應該先做完本次週期內部的工作,然後進入“善後階段”完成一些善後的工作,所謂的兩階段終止,即中止“運作階段”,並完成“善後階段”,完整的完成執行緒的工作。

兩階段終止執行緒的架構模式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class WorkerTerminalThread extends Thread {
       // 已經送出終止請求為true,初始化的時候為false
       //由於該欄位可能會被多個執行緒訪問修改,為了保護就使用這個
    private volatile boolean shutdownRequested = false;
    // 終止請求
    public void shutdownRequest() {
        shutdownRequested = true;
        interrupt();
    }
    public boolean isShutdownRequest() {
        return shutdownRequested;
    }
    // 具體動作
    public final void run() {
        try {
            while (!shutdownRequested)
                doWork();
        catch (InterruptedException e) {
        }
        // 終止處理中的工作,不會進行平常操作,但是會進行終止處理
        finally {
            doShutdown();
        }
    }
    // 具體工作操作
    private void doWork() throws InterruptedException {
    }
    // 終止後進行善後處理
    private void doShutdown()
    {
    }
}

解釋:

  1,利用Volatile的原因是,這個欄位可能會被多個執行緒所使用,進行修改,為了保護該欄位,則可以利用同步方法或者同步程式碼塊來保護,或者利用Volatile。用Volatile修飾的欄位,強制了該成員變數在每次被執行緒訪問時,都強迫從共享記憶體中重讀該成員變數的值。而且,當成員變數發生變化時,強迫執行緒將變化值回寫到共享記憶體。這樣在任何時刻,兩個不同的執行緒總是看到某個成員變數的同一個值。

  2,這裡運用了標識和中斷狀態來終止執行緒,之所以不單獨用一個。原因是如果僅僅利用標識,無法是的那些處於wait、sleep或者join中的執行緒馬上停止,響應性就會很差。加入了interrupt後,就可以立刻使得這些狀態下的執行緒中斷。如果僅僅利用interrupt,由於interrupt僅僅對於wait,sleep或join處進行丟擲異常,如果工作程式碼執行在catch裡,捕獲了InterruptedException後,則此時interrupt就不起作用了。

本文轉自 zhao_xiao_long 51CTO部落格,原文連結:http://blog.51cto.com/computerdragon/1206548


相關文章