ในส่วนก่อนหน้า "การขัดจังหวะเธรด" เราได้อธิบายวิธีการขัดจังหวะเธรดที่กำลังดำเนินการ และสิ่งที่เราต้องทำกับ Thread เพื่อขัดจังหวะเธรด โดยทั่วไป เราสามารถใช้กลไกการขัดจังหวะที่แนะนำในส่วนก่อนหน้าได้ อย่างไรก็ตาม หากเธรดใช้อัลกอริธึมที่ซับซ้อนซึ่งกระจายไปตามหลายวิธี หรือหากมีการเรียกซ้ำในการเรียกเมธอด เราควรใช้วิธีที่ดีกว่าในการควบคุมการหยุดชะงักของเธรด เพื่อจุดประสงค์นี้ Java จัดเตรียม InterruptedException ข้อยกเว้นนี้สามารถเกิดขึ้นได้เมื่อมีการตรวจพบและตรวจพบคำขอขัดจังหวะในเมธอด run()
ในส่วนนี้ เราจะใช้เธรดเพื่อค้นหาไฟล์ในไดเร็กทอรีที่ระบุและไดเร็กทอรีย่อยเพื่อสาธิตการควบคุมการหยุดชะงักของเธรดโดยใช้ InterruptedException
รู้ว่ามัน
ทำตามขั้นตอนที่แสดงด้านล่างเพื่อใช้งานโปรแกรมตัวอย่าง
1. สร้างคลาสชื่อ FileSearch และใช้อินเทอร์เฟซ Runnable รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
FileSearch คลาสสาธารณะใช้ Runnable {
2. ประกาศตัวแปรสองตัว ตัวหนึ่งสำหรับชื่อไฟล์ที่จะค้นหา และอีกตัวหนึ่งสำหรับการเริ่มต้นไดเร็กทอรีที่จะค้นหา ใช้ตัวสร้างของคลาส และเริ่มต้นตัวแปรสองตัวที่เพิ่งประกาศด้วยพารามิเตอร์ของตัวสร้าง รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
สตริงส่วนตัว initPath;
ชื่อไฟล์สตริงส่วนตัว;
FileSearch สาธารณะ (สตริง initPath, ชื่อไฟล์สตริง) {
this.initPath = initPath;
this.fileName = ชื่อไฟล์;
-
3. ใช้เมธอด run() ซึ่งจะตรวจสอบว่า fileName เป็นชื่อพาธหรือไม่ หากเป็นเช่นนั้น ให้เรียกใช้เมธอด directoryProcess() เพื่อประมวลผล เมธอด directoryProcess() พ่น InterruptedException ดังนั้นเราจึงจำเป็นต้องจับข้อยกเว้น รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
@แทนที่
โมฆะสาธารณะวิ่ง () {
ไฟล์ไฟล์ = ไฟล์ใหม่ (initPath);
ถ้า (file.isDirectory()) {
พยายาม {
กระบวนการไดเร็กทอรี (ไฟล์);
} จับ (InterruptedException e) {
System.out.printf("%s: การค้นหาถูกขัดจังหวะ",
Thread.currentThread().getName());
-
-
-
ในบทความต้นฉบับ ชื่อเมธอดที่กล่าวถึงคือ processDirectory() อย่างไรก็ตาม ตามขั้นตอนด้านล่าง ถือเป็นข้อผิดพลาดของเสมียน ดังนั้นให้ถูกต้อง
4. ใช้เมธอด directoryProcess() เมธอดนี้จะอ่านไฟล์และไดเร็กทอรีย่อยทั้งหมดในไดเร็กทอรีที่ระบุ จากนั้นจึงประมวลผล สำหรับแต่ละไดเร็กทอรี เมธอดนี้จะทำการเรียกซ้ำเพื่อประมวลผลไดเร็กทอรีที่ระบุโดยพารามิเตอร์ สำหรับแต่ละไฟล์ เมธอดนี้จะเรียกเมธอด fileProcess() หลังจากประมวลผลไดเร็กทอรีและไฟล์ทั้งหมดแล้ว วิธีนี้จะตรวจสอบว่าเธรดถูกขัดจังหวะหรือไม่ ซึ่งก็คือการส่งข้อยกเว้น InterruptedException รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
-
* ประมวลผลไดเร็กทอรี
-
* ไดเร็กทอรีไฟล์ @param ที่จะประมวลผล
* @throws InterruptedException
-
ไดเร็กทอรีโมฆะส่วนตัวกระบวนการ (ไฟล์ไฟล์) พ่น InterruptedException {
ไฟล์[] รายการ = file.listFiles();
ถ้า (null != รายการ) {
สำหรับ (int i = 0; i < list.length; i++) {
ถ้า (รายการ [i] .isDirectory ()) {
ไดเรกทอรีกระบวนการ (รายการ [i]);
} อื่น {
กระบวนการไฟล์ (รายการ [i]);
-
-
-
ถ้า (Thread.interrupted()) {
โยน InterruptedException ใหม่ ();
-
-
5. ใช้เมธอด fileProcess() ซึ่งเปรียบเทียบไฟล์ที่กำลังประมวลผลกับชื่อไฟล์ที่จะพบ หากชื่อไฟล์เท่ากัน ข้อความจะถูกพิมพ์ไปยังคอนโซล เธรดจะตรวจสอบเพื่อดูว่ามีการขัดจังหวะหรือไม่ และหากเป็นเช่นนั้น จะส่ง InterruptedException รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
-
* ไฟล์ที่ประมวลผลแล้ว
-
* ไฟล์ไฟล์ @param ที่จะประมวลผล
* @throws InterruptedException
-
fileProcess เป็นโมฆะส่วนตัว (ไฟล์ไฟล์) พ่น InterruptedException {
ถ้า (file.getName().เท่ากับ(ชื่อไฟล์)) {
System.out.printf("%s : %s/n",
Thread.currentThread().getName()
ไฟล์getAbsolutePath());
-
ถ้า (Thread.interrupted()) {
โยน InterruptedException ใหม่ ();
-
-
6. ตอนนี้ นำคลาสหลักของตัวอย่างไปใช้ และใช้เมธอด main() รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
ชั้นเรียนสาธารณะหลัก {
โมฆะคงที่สาธารณะ main (String [] args) {
7. สร้างและเตรียมใช้งานวัตถุ FileSearch จากนั้นสร้างวัตถุ Thread เพื่อดำเนินงาน จากนั้นให้เริ่มเธรด รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
FileSearch fileSearch = new FileSearch("C://", "autoexec.bat");
เธรดเธรด = เธรดใหม่ (fileSearch);
เธรด.เริ่มต้น();
8. รอสิบวินาทีแล้วขัดจังหวะเธรด รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
พยายาม {
TimeUnit.SECONDS.sleep (10);
} จับ (InterruptedException e) {
e.printStackTrace();
-
เธรด.ขัดจังหวะ();
9. ดำเนินการตามตัวอย่างและดูผลลัพธ์
รู้ว่าทำไม
ต่อไปนี้คือผลลัพธ์ของการดำเนินการเธรด สามารถดูได้จากเอาต์พุตว่าการดำเนินการเธรดสิ้นสุดลงอย่างไรเมื่อ FileSearch ตรวจพบว่าถูกขัดจังหวะ
คัดลอกรหัสรหัสดังต่อไปนี้:
เธรด-0: C:/autoexec.bat
Thread-0: การค้นหาถูกขัดจังหวะ
ในตัวอย่างนี้ เราใช้ข้อยกเว้น Java เพื่อควบคุมการหยุดชะงักของเธรด เมื่อคุณรันตัวอย่าง โปรแกรมจะตรวจสอบว่าไดเร็กทอรีที่ระบุและไดเร็กทอรีย่อยมีไฟล์เป้าหมายหรือไม่ ตัวอย่างเช่น หากคุณป้อน /b/c/d โปรแกรมจะเรียกเมธอด directoryProcess() ซ้ำสามครั้ง เมื่อเธรดตรวจพบว่าถูกขัดจังหวะ InterruptedException จะถูกโยนทิ้ง ไม่ว่าจะดำเนินการเรียกซ้ำกี่ครั้งก็ตาม โปรแกรมจะเริ่มดำเนินการเมธอด run()
ไม่มีวันสิ้นสุด
โดยทั่วไปข้อยกเว้น InterruptedException จะถูกส่งออกไปโดย API ทำงานพร้อมกันของ Java เช่นเมธอด sleep()
ใช้หลักคำสอน
บทความนี้แปลมาจาก "Java 7 Concurrency Cookbook" (D Gua Ge ขโมยมาในชื่อ "Java7 Concurrency Example Collection") และใช้เป็นสื่อการเรียนรู้เท่านั้น ห้ามนำไปใช้เพื่อวัตถุประสงค์ทางการค้าใดๆ โดยไม่ได้รับอนุญาต
ความสำเร็จเล็กๆ น้อยๆ
รหัสที่สมบูรณ์ของคลาส FileSearch เป็นดังนี้:
แพ็คเกจ com.diguage.books.concurrencycookbook.chapter1.recipe4;
นำเข้า java.io.File;
-
* วันที่: 18-09-2556
* เวลา: 18:21 น
-
FileSearch คลาสสาธารณะใช้ Runnable {
สตริงส่วนตัว initPath;
ชื่อไฟล์สตริงส่วนตัว;
-
* ตัวสร้างการเริ่มต้น
-
* @param initPath ไดเร็กทอรีที่จะค้นหา
* @param fileName ชื่อของไฟล์ที่จะค้นหา
-
FileSearch สาธารณะ (สตริง initPath, ชื่อไฟล์สตริง) {
this.initPath = initPath;
this.fileName = ชื่อไฟล์;
-
@แทนที่
โมฆะสาธารณะวิ่ง () {
ไฟล์ไฟล์ = ไฟล์ใหม่ (initPath);
ถ้า (file.isDirectory()) {
พยายาม {
กระบวนการไดเร็กทอรี (ไฟล์);
} จับ (InterruptedException e) {
System.out.printf("%s: การค้นหาถูกขัดจังหวะ",
Thread.currentThread().getName());
-
-
-
-
* ประมวลผลไดเร็กทอรี
-
* ไดเร็กทอรีไฟล์ @param ที่จะประมวลผล
* @throws InterruptedException
-
ไดเร็กทอรีโมฆะส่วนตัวกระบวนการ (ไฟล์ไฟล์) พ่น InterruptedException {
ไฟล์[] รายการ = file.listFiles();
ถ้า (null != รายการ) {
สำหรับ (int i = 0; i < list.length; i++) {
ถ้า (รายการ [i] .isDirectory ()) {
ไดเรกทอรีกระบวนการ (รายการ [i]);
} อื่น {
กระบวนการไฟล์ (รายการ [i]);
-
-
-
ถ้า (Thread.interrupted()) {
โยน InterruptedException ใหม่ ();
-
-
-
* ไฟล์ที่ประมวลผลแล้ว
-
* ไฟล์ไฟล์ @param ที่จะประมวลผล
* @throws InterruptedException
-
fileProcess เป็นโมฆะส่วนตัว (ไฟล์ไฟล์) พ่น InterruptedException {
ถ้า (file.getName().เท่ากับ(ชื่อไฟล์)) {
System.out.printf("%s : %s/n",
Thread.currentThread().getName()
ไฟล์getAbsolutePath());
-
ถ้า (Thread.interrupted()) {
โยน InterruptedException ใหม่ ();
-
-
-
รหัสที่สมบูรณ์ของคลาสหลัก
คัดลอกรหัสรหัสดังต่อไปนี้:
แพ็คเกจ com.diguage.books.concurrencycookbook.chapter1.recipe4;
นำเข้า java.util.concurrent.TimeUnit;
-
* วันที่: 18-09-2556
* เวลา: 19:28 น
-
ชั้นเรียนสาธารณะหลัก {
โมฆะคงที่สาธารณะ main (String [] args) {
FileSearch fileSearch = new FileSearch("C://", "autoexec.bat");
เธรดเธรด = เธรดใหม่ (fileSearch);
เธรด.เริ่มต้น();
พยายาม {
TimeUnit.SECONDS.sleep (10);
} จับ (InterruptedException e) {
e.printStackTrace();
-
เธรด.ขัดจังหวะ();
-
-