1. 程式人生 > 遊戲攻略 >《永劫無間》迦南美杜莎捏臉資料分享

《永劫無間》迦南美杜莎捏臉資料分享

1. 如何停止一個執行緒?

官方停止執行緒的方法被廢棄了,所以不能直接停止執行緒,這麼做是非常不安全的。

2. 為什麼不能簡單停止一個執行緒?

因為,簡單停止一個執行緒會出現很多異常情況,比如:多執行緒讀取共享變數時,其中一個執行緒加鎖了,其它執行緒處於等待狀態,如果,將加鎖執行緒暫停了,那麼其它執行緒就會被堵塞在這裡,不能釋放,假如加鎖執行緒在等待其它執行緒中某個執行緒的釋放鎖,那麼,就會出現死鎖。所以,執行緒中的暫停方法也被廢棄了。如果,直接使用stop方法停止執行緒,執行緒立刻被回收,被堵塞的執行緒立刻獲得鎖許可權並加鎖,然後去操作共享變數,此時發現共享記憶體有一堆莫名資料或者狀態,這些資料原因是前一個執行緒在被停止時立刻被回收了,沒有來的及處理完成,就被其它執行緒獲得加鎖操作了,那麼,這個執行緒也會出現異常,甚至Crash。

3. 如何安全的停止一個執行緒?

通過執行緒自行結束,而不是強行停止,目標執行緒應當具有處理中斷能力。也是在使用執行緒過程中要通過結束任務從而停止執行緒。通過執行緒任務而停止執行緒,和停止執行緒結果上沒什麼區別,但是,和通過停止執行緒的方法結束執行緒的方式相比,結果有明顯區別,停止執行緒是不安全的做法,而通過邏輯控制結束任務從而結束執行緒卻是安全的做法。

通過邏輯中斷執行緒的方式:

  1. 使用Thread內建的interrupted()(中止)方法:

@FastNative
public static native boolean interrupted();

  但是,線上程中要新增識別中止狀態的邏輯:

Thread thread = new Thread() {
    @Override
    public void run() {
        for (int idx = 0; idx < 1000000; idx++) {
            // interrupted()
            if (isInterrupted()) {
                break;
            }

            // TODO: 2020/6/1
        }
    }
};

thread.start();
// 呼叫中斷方法,傳送中斷執行緒狀態
thread.interrupt();

  獲取中止狀態的方法有兩個,分別是isInterrupted()和interrupted(),其中interrupted()是靜態方法,兩個方法的區別:

  isInterrupted():是簡單的讀取該執行緒的中斷狀態,不清空可以重複呼叫,直到狀態清空前一直返回true。

  interrupted():是靜態方法,獲取該執行緒的中斷狀態,並清空狀態。中斷狀態呼叫後清空,後續再呼叫返回false。

  2. volatile boolean 標誌位,就是自己實現中斷邏輯:

class InterruptThread extends Thread {
    public volatile boolean isStopped = false;
    
    @Override
    public void run() {
        super.run();
        
        for (int idx = 0; idx < 100000; idx++) {
            if (isStopped) {
                return;
            }
            
            System.out.println("test");
        }
    }
}

void test() {
    InterruptThread thread = new InterruptThread();
    thread.start();
    thread.isStopped = true

}