程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 漫談並發編程(四):終結任務

漫談並發編程(四):終結任務

編輯:C++入門知識

漫談並發編程(四):終結任務


使用狀態變量來終結任務

有時我們可以使用一個狀態變量(如布爾值)來終結任務的執行,這種方式非常平和,且提供給你機會在任務終止前做一些操作。如:
public class StateStopTask implements Runnable{
     private static volatile boolean isCancled = false;
     public void run() {
          while(true) {
               if(isCancled == true) {
                    System.out.println("StateStopTask is stop");
                    return;
               }
          }
     }

     public static void main(String []args) {
          new Thread(new StateStopThread()).start();
          Thread.sleep(3000);
          isCancled = true;
     }
}
或者直接使用Thread.interrupt()來設置線程的中斷標識,並且在程序中檢測該標識,可以避免狀態變量的定義。
public class StateStopTask implements Runnable{
     public void run() {
          while(!Thread.currentThread().isInterrupted()) {
                System.out.println("StateStopTask is running");
          }
          System.out.println("StateStopTask is stopping");
     }
     public static void main(String []args) {
          Thread t = new Thread(new StateStopThread()).start();
          Thread.sleep(3000);
          t.interrupt();
     }
}

在阻塞時終結

前面使用狀態變量只能在線程運行到該檢測時才能終止,有時我們需要線程無論在何時何地都能夠被終止,尤其是在阻塞的時候。一個任務進入阻塞狀態,可能有如下原因: 通過調用sleep(milliseconds)使任務進入休眠狀態,在這種情況下,任務在指定的時間內不會運行。你可以通過wait()使線程掛起。直到線程得到了notify()或notifyAll()消息(或者在JavaSE5的java.util.concurrent類庫中等價的signal()或signalAll()消息),線程才會進入就緒狀態。任務在等待某個輸入輸出完成。任務試圖在某個對象上調用其同步控制方法,但是對象鎖不可用,因為另一個任務已經獲取了這個鎖。 中斷 程序在由於sleep或者wait()導致的阻塞情況下,如果被調用interrupt()方法將拋出interruptedExcetion異常,並且中斷狀態將清除。程序在由於IO和鎖的阻塞時,調用interrupt()方法不會拋出interruptedException,但會設置中斷狀態。使用interrupted()可以檢測中斷狀態並且如果正處於中斷則清除中斷狀態,所以在程序中一般使用下面的方式檢測中斷,並做善後處理:
public class InterruptedTask implements Runnable{
     public void run() {
          while(!Thread.currentThread().interrupted()) {
               try {
                    System.out.println("InterruptedTask running");
                    Thread.sleep(100);     
               } catch (InterruptedException e) {
                    System.out.println("interrupted by InterruptedException ")
               }     
          }
          System.out.println("InterruptedTask Interrupted")

     }
}
現代java代碼不推薦直接操作Thread對象,轉而盡量通過Executor來執行所有操作。如果你在Executor上調用shutdownNow(),那麼它將發送一個interrupt()調用給它啟動的所有線程。這樣做是常見的,因為一個Executor通常執行同一類任務,所以經常會希望關閉Executor的所有任務。然後,你有時會希望只中斷單一的任務。如果使用Executor,那麼通過調用submit()而不是executor()來啟動任務,就可以持有該任務的上下文,submit()將返回一個泛型Future,其中有一個未修飾的參數,因為你不能調用get(),使用這個Futrue對象可以調用cancle(),如果傳遞true給cancle(),那麼在這個線程上就會調用interrupt()方法。 一般由於鎖而導致的阻塞無法中斷,但原子鎖(ReentrantLock)支持可中斷的阻塞操作lockInterruptibly()。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved