Java並發編程示例(四):可控的線程中止。本站提示廣大學習愛好者:(Java並發編程示例(四):可控的線程中止)文章只能為提供參考,不一定能成為您想要的結果。以下是Java並發編程示例(四):可控的線程中止正文
在上一節“線程中止”中,我們講授了若何中止一個正在履行的線程和為了中止線程,我們必需對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();
}
}