国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java并發編程示例(四):可控的線程中斷

2019-11-26 15:20:37
字體:
來源:轉載
供稿:網友

在上一節“線程中斷”中,我們講解了如何中斷一個正在執行的線程以及為了中斷線程,我們必須對Thread動點什么手腳。一般情況下,我們可以使用上一節介紹的中斷機制。但是,如果線程實現了一個分配到多個方法中的復雜算法,或者方法調用中有一個遞歸調用,我們應該使用更好的方式來控制線程的中斷。為此,Java提供了InterruptedException異常。當檢測到中斷請求時,可以拋出此異常,并且在run()方法中捕獲。

在本節,我們將使用一個線程查找指定目錄及其子目錄下文件來演示通過使用InterruptedException異??刂凭€程中斷。

知其然

按照下面所示步驟,實現示例程序。

1.創建一個名為FileSearch的類,并且實現Runnable接口。代碼如下:

復制代碼 代碼如下:

public class FileSearch implements Runnable {

2.聲明兩個變量,一個用于需要查找的文件名,一個用于初始化查找的目錄;實現類的構造函數,并用構造函數的參數初始化剛剛聲明的兩個變量。代碼如下:

復制代碼 代碼如下:

private String initPath;
private String fileName;

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

3.實現run()方法,該方法檢查fileName是否一個路徑名稱。如果是,則調用directoryProcess()方法進行處理。directoryProcess()方法會拋出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());
        }
    }
}

原文中,提到的方法名稱為processDirectory()。但是,根據下文的程序,屬于筆誤。故改正。

4.實現directoryProcess()方法。該方法讀取指定目錄下的所有文件以及子目錄再進行處理。對于每一個目錄,該方法進行一個遞歸調用,來處理參數指定的目錄。對于每一個文件,該方法會調用fileProcess()方法。在處理完所有的目錄以及文件后,該方法會檢查線程是否被中斷,這是拋出一個InterruptedException異常。代碼如下:

復制代碼 代碼如下:

/**
 * 處理一個目錄
 *
 * @param file 需要處理的目錄
 * @throws InterruptedException
 */
private void directoryProcess(File file) throws InterruptedException {
    File[] list = file.listFiles();
    if (null != list) {
        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.實現fileProcess()方法,該方法會比較正在處理的文件和需要查找的文件名。如果文件名稱相等,則在控制臺打印出一條信息。然后,線程檢查是否被中斷,如果是,則拋出InterruptedException異常。代碼如下:

復制代碼 代碼如下:

/**
 * 處理的文件
 *
 * @param file 需要處理的文件
 * @throws 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()方法。代碼如下:
復制代碼 代碼如下:

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

7.創建并初始化FileSearch對象,然后創建一個Thread對象,來執行該任務。然后,啟動該線程。代碼如下:
復制代碼 代碼如下:

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

8.等待十秒鐘,然后中斷線程。代碼如下:

復制代碼 代碼如下:

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

thread.interrupt();

9.執行該示例,查看結果。

知其所以然

下面是線程執行的結果。從輸出中可以看出,當FileSearch檢測到被中斷后,如何中止線程執行的。

復制代碼 代碼如下:

Thread-0 : C:/autoexec.bat
Thread-0: The search has been interrupted

本示例中,我們使用Java的異常來控制線程的中斷。當你運行示例時,程序會檢測指定目錄及其子目錄是否包含目標文件。例如,如果輸入/b/c/d,程序將會遞歸調用三次directoryProcess()方法。當線程檢測到其被中斷,則會拋出InterruptedException異常,無論執行多少次遞歸調用,程序都會開始執行run()方法。

永無止境

InterruptedException異常一般由Java并發API,例如sleep()方法,拋出。

拿來主義

本文是從 《Java 7 Concurrency Cookbook》 (D瓜哥竊譯為 《Java7并發示例集》 )翻譯而來,僅作為學習資料使用。沒有授權,不得用于任何商業行為。

小有所成

FileSearch類的完整代碼

復制代碼 代碼如下:

package com.diguage.books.concurrencycookbook.chapter1.recipe4;

import java.io.File;

/**
 * Date: 2013-09-18
 * Time: 18:21
 */
public class FileSearch implements Runnable {
    private String initPath;
    private String fileName;

    /**
     * 初始化構造函數
     *
     * @param initPath 需要進行查找的目錄
     * @param 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());
            }
        }
    }

    /**
     * 處理一個目錄
     *
     * @param file 需要處理的目錄
     * @throws InterruptedException
     */
    private void directoryProcess(File file) throws InterruptedException {
        File[] list = file.listFiles();
        if (null != list) {
            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();
        }
    }

    /**
     * 處理的文件
     *
     * @param file 需要處理的文件
     * @throws 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();
        }
    }
}

Main類的完整代碼

復制代碼 代碼如下:

package com.diguage.books.concurrencycookbook.chapter1.recipe4;

import java.util.concurrent.TimeUnit;

/**
 * Date: 2013-09-18
 * Time: 19:28
 */
public class Main {
    public static void main(String[] args) {
        FileSearch fileSearch = new FileSearch("C://", "autoexec.bat");
        Thread thread = new Thread(fileSearch);
        thread.start();

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

        thread.interrupt();
    }
}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阳曲县| 桦甸市| 五原县| 东山县| 天镇县| 青海省| 临湘市| 潞西市| 桃江县| 兴义市| 绥德县| 广汉市| 桂阳县| 铅山县| 盐城市| 瑞安市| 如皋市| 武山县| 博客| 五指山市| 松江区| 保山市| 苍山县| 鸡西市| 佛坪县| 长治市| 舟山市| 双城市| 兴化市| 永清县| 密云县| 东辽县| 石渠县| 云梦县| 济阳县| 岱山县| 绍兴市| 常熟市| 岳西县| 象山县| 岢岚县|