Java 7 Concurrency Cookbook 翻譯 第一章 線程管理之二

來源:互聯網
上載者:User

標籤:api   tab   exit   bsp   線程   遞迴調用   art   dex   print   

三、中斷一個線程

  一個擁有多個線程的Java程式要結束,需要滿足兩個條件之一:一是所有的非後台線程都執行結束了;二是某個線程執行了 System.exit() 方法。當你想要終結一個運行中的Java程式或者程式的使用者想要取消一個線程正在執行的任務時,你都需要結束一個線程。

  Java提供中斷機制來表明我們想要終止一個線程。這個機制的核心是線程必須要檢查自己是否被中斷,而且線程自己決定是否響應插斷要求。線程可以忽略該插斷要求而繼續執行。

  在本秘訣中,我們將開發一個程式,這個程式建立線程,5秒後使用中斷機制來結束線程。

public class Main {    public static void main(String[] args) {        Thread task = new PrimeGenerator();        task.start();                try {            Thread.sleep(5000);        } catch (InterruptedException e) {            e.printStackTrace();        }                task.interrupt();    }}public class PrimeGenerator extends Thread {    @Override    public void run() {        long number = 1L;        while (true) {            if (isPrime(number)) {                System.out.printf("Number "+ number +" is Prime");            }                        if (isInterrupted()) {                System.out.printf("The Prime Generator has been Interrupted");                return;            }            number++;        }    }        private boolean isPrime(long number) {        if (number <= 2) {            return true;        }        for (long i = 2; i < number; i++) {            if ((number % i) == 0) {                return false;            }        }        return true;    }}

  在 Thread 類中有一個 boolean 類型的屬性來表明該類對應的線程是否被中斷。通過調用 Thread 對象的 interrupt() 方法,設定其對應的線程被中斷。而 isInterrupted() 方法用來返回對應線程是否被中斷的狀態。

  Thread 類還有一個靜態方法 interrupted() 同樣可以返回所線上程是否被中斷的狀態。但是該方法還有一個副作用:就是把線程的被中斷狀態重設為 false。

  線程可以忽略其被中斷的狀態,但這通常不是好的編程習慣。

四、控制線程的中斷狀態

  在上一個秘訣中,你學習了如何去中斷一個線程和如何去控制線程的中斷狀態。如果你要中斷執行的只是一個簡單的線程,那麼上一個秘訣就足夠了。但是,如果該線程實現了一個分成多個方法的複雜演算法,或者它含有實現了遞迴演算法的方法,我們應該使用一種更好的機制去該線程的中斷狀態。為此,Java提供了 InterruptedException。當你在 run() 方法裡發現了線程被中斷時,你可以拋出並捕獲該異常。

  在本秘訣中,我們的線程在目錄和其子目錄中來尋找含有特定名稱的檔案,這個程式展示如何使用 InterruptedException 來控制線程的中斷。

public class FileSearch implements Runnable{    private String initPath;    private String fileName;    public FileSearch(String initPath, String fileName) {        this.initPath = initPath;        this.fileName = fileName;    }    @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());            }        }    }        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();        }    }        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();        }    }}public class Main {    public static void main(String[] args) {        FileSearch search = new FileSearch("C:\\", "autoexec.bat");        Thread thread = new Thread(search);        thread.start();                try {            TimeUnit.SECONDS.sleep(10);        } catch (InterruptedException e) {            e.printStackTrace();        }                thread.interrupt();    }}

  在這個例子中,我們使用異常機制來達到終止線程啟動並執行目的。你運行此樣本程式,程式開始遍曆目錄並尋找特定的檔案。一旦線程檢查到自己被中斷了,它就拋出 InterruptedException 異常,繼續執行 run() 方法的代碼,多層的遞迴調用對結果沒實質影響。

  Java並發API中的 sleep() 方法也有可能拋出 InterruptedException異常。

  筆者總結:本秘訣本質還是線程自己檢查是否被中斷,發現被中斷後,通過拋出異常的方式直接跳轉到了異常捕獲代碼處,是否多層遞迴對此異常跳轉機制沒影響。

  重要:本系列翻譯文檔也會在本人的公眾號(此山是我開)第一時間發布,歡迎大家關注。

 

Java 7 Concurrency Cookbook 翻譯 第一章 線程管理之二

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.