1. 程式人生 > >執行緒管理(四)操作執行緒的中斷機制

執行緒管理(四)操作執行緒的中斷機制

宣告:本文是《 Java 7 Concurrency Cookbook 》的第一章, 作者: Javier Fernández González 譯者:鄭玉婷 校對:歐振聰

操作執行緒的中斷機制

在之前的指南里,你學習瞭如何中斷執行執行緒和如何對Thread物件的中斷控制。之前例子中的機制可以很容易中斷的執行緒中使用。但是如果執行緒實現的是由複雜的演算法分成的一些方法,或者它的方法有遞迴呼叫,那麼我們可以用更好的機制來控制執行緒中斷。為了這個Java提供了InterruptedException異常。當你檢測到程式的中斷並在run()方法內捕獲,你可以拋這個異常。

在這個指南中, 我們將實現的執行緒會根據給定的名稱在檔案件和子資料夾裡查詢檔案,這個將展示如何使用InterruptedException異常來控制執行緒的中斷。

準備

指南中的例子是使用Eclipse IDE 來實現的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 開啟並建立一個新的java專案。

怎麼做呢

按照這些步驟來實現下面的例子::

1.   建立一個名為FileSearch的類,並一定要實現Runnable介面。

public class FileSearch implements Runnable {

2.   宣告2個為private的屬性,一個是為了我們要查詢的檔名和另一個是為了初始資料夾。為這個類實現一個建構函式,並初始化這些屬性。

private String initPath;
private String fileName;
public FileSearch(String initPath, String fileName) {
   this.initPath = initPath;
   this.fileName = fileName;
}

3.   為FileSearch類實現run()方法。 它會檢測fileName屬性是不是路徑,如果它是,就呼叫processDirectory()方法。這個方法會丟擲一個InterruptedException異常,所以我們應該要捕獲它。

@Override
public void run() {
File file = new File(initPath);
if (file.isDirectory()) {
  try {
    directoryProcess(file);
  } catch (InterruptedException e) {
    System.out.printf("%s: The search has been interrupted",Thread.currentThread().getName());
  }
 }
}

4.   實現 directoryProcess()方法。這個方法會獲取資料夾的檔案和子資料夾並處理他們。對於每個路徑,這個方法會傳遞路徑作為引數來迴圈呼叫。對於每個檔案,它會呼叫fileProcess()方法。處理完全部的檔案和資料夾後,它會檢查執行緒有沒有被中斷,在這個例子,會丟擲一個InterruptedException異常。

private void directoryProcess(File file) throws
InterruptedException {
 File list[] = file.listFiles();
 if (list != null) {
    for (int i = 0; i < list.length; i++) {
       if (list[i].isDirectory()) {
          directoryProcess(list[i]);
       } else {
          fileProcess(list[i]);
       }
   }
}
if (Thread.interrupted()) {
     throw new InterruptedException();
}
}

5.   實現 processFile()方法。這方法會比較檔案的名字與我們要搜尋的檔名。如果他們一樣,就寫一條資訊到控制檯。比較完後,執行緒會檢查有沒有被中斷,在這裡,它會丟擲一個InterruptedException異常。

private void fileProcess(File file) throws InterruptedException
{
  if (file.getName().equals(fileName)) {
     System.out.printf("%s : %s\n",Thread.currentThread().getName() ,file.getAbsolutePath());
  }
  if (Thread.interrupted()) {
     throw new InterruptedException();
  }
}

6.   現在, 讓我們來實現例子的主類吧。實現一個Main類幷包含main()方法。

public class Main {
public static void main(String[] args) {

7.   建立並初始一個FileSearch類的物件和一個執行它的任務的執行緒。然後,開始執行執行緒。

FileSearch searcher=new FileSearch("C:\\","autoexec.bat");
Thread thread=new Thread(searcher);
thread.start();

8.   等10秒然後中斷執行緒。

try {
   TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
   e.printStackTrace();
}
thread.interrupt();
}

9.   執行例子並檢視結果。

它是怎麼工作的

下面的截圖給出了例子的執行結果。你可以發現FileSearch物件是如何執行的,當它檢測到它被中斷時。請看裁圖:

在這個例子, 我們使用Java異常來控制執行緒的中斷。當你執行這個例子,程式開始瀏覽資料夾來檢查他們是否含有那個檔案。例如,如果你輸入\b\c\d,那麼程式會迴圈呼叫3次processDirectory()方法。當它檢測到被中斷時,它會丟擲InterruptedException異常並繼續執行方法,無論已經多少次迴圈呼叫。

更多

InterruptedException 異常是由一些與併發API有關的Java方法,如sleep()丟擲的。

參見

  • 第一章,執行緒管理:執行緒的中斷指南