ในโปรแกรม Java แบบมัลติเธรด โปรแกรมทั้งหมดจะไม่ออกจนกว่าเธรดทั้งหมดจะดำเนินการเสร็จสิ้น (ควรสังเกตว่าการดำเนินการของเธรดที่ไม่ใช่ daemon ทั้งหมดเสร็จสมบูรณ์แล้ว หากเธรดดำเนินการตามเมธอด System.exit() โปรแกรมก็จะออกเช่นกัน) บางครั้ง คุณต้องการยกเลิกการเรียกใช้งานเธรด เช่น หากคุณต้องการออกจากโปรแกรม หรือต้องการยกเลิกงานที่กำลังดำเนินการอยู่ เป็นต้น
Java มีกลไกการขัดจังหวะที่ช่วยให้เราสามารถขัดจังหวะเธรดที่เราต้องการยุติการดำเนินการได้อย่างชัดเจน คุณลักษณะหนึ่งของกลไกการขัดจังหวะคือเราสามารถตรวจสอบว่าเธรดถูกขัดจังหวะหรือไม่ จากนั้นจึงตัดสินใจว่าจะตอบสนองต่อคำขอยกเลิกหรือไม่ เธรดยังสามารถละเว้นคำขอยกเลิกและดำเนินการต่อไปได้
ในส่วนนี้ โปรแกรมตัวอย่างที่เราพัฒนาจะสร้างเธรด และหลังจากผ่านไปห้าวินาที ให้ใช้กลไกการขัดจังหวะเพื่อยุติเธรดอย่างแข็งขัน
รู้ว่ามัน
ทำตามขั้นตอนด้านล่างเพื่อเสร็จสิ้นโปรแกรมตัวอย่าง
1. สร้างคลาสชื่อ PrimeGenerator และสืบทอดคลาส Thread รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
PrimeGenerator ระดับสาธารณะขยายเธรด {
2. เขียนเมธอด run() ใหม่และเพิ่มการวนซ้ำไม่สิ้นสุดในเมธอดดังกล่าว ให้ตรวจสอบว่าจำนวนเต็มบวกที่ต่อเนื่องกันซึ่งเริ่มต้นจาก 1 เป็นจำนวนเฉพาะโดยการคำนวณหรือไม่ หากเป็นเช่นนั้น ให้พิมพ์ไปที่คอนโซล รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
@แทนที่
โมฆะสาธารณะวิ่ง () {
ตัวเลขยาว = 1L;
ในขณะที่ (จริง) {
ถ้า (isPrime (หมายเลข)) {
System.out.printf("หมายเลข %d /tis Prime.", หมายเลข);
-
3. หลังจากประมวลผลตัวเลขแล้ว ให้ตรวจสอบว่าเธรดถูกขัดจังหวะหรือไม่โดยการเรียกเมธอด isInterrupted() หากวิธีนี้คืนค่าเป็นจริง ประโยคจะถูกพิมพ์ไปยังคอนโซล จากนั้นการดำเนินการเธรดจะสิ้นสุดลง รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
ถ้า (ถูกขัดจังหวะ ()) {
System.out.println("ตัวสร้างนายกรัฐมนตรีถูกขัดจังหวะ");
กลับ;
-
หมายเลข++;
-
-
4. ใช้เมธอด isPrime() ซึ่งใช้ในการพิจารณาว่าพารามิเตอร์เป็นจำนวนเฉพาะหรือไม่ หากเป็นเช่นนั้น จะคืนค่าเป็นจริง หรือไม่เช่นนั้นก็จะคืนค่าเท็จ รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
-
* พิจารณาว่าพารามิเตอร์เป็นจำนวนเฉพาะหรือไม่
-
* @param number ตัวเลขที่จะตัดสิน
* @กลับ
-
บูลีนส่วนตัว isPrime (ตัวเลขยาว) {
ถ้า (หมายเลข <= 2) {
กลับเป็นจริง;
-
สำหรับ (int i = 2; i < หมายเลข; i++) {
ถ้า ((จำนวน % i) == 0) {
กลับเท็จ;
-
-
กลับเป็นจริง;
-
5. ตอนนี้ นำคลาสหลักของโปรแกรมตัวอย่าง คลาส Main และเมธอด main() ไปใช้ รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
ชั้นเรียนสาธารณะหลัก {
โมฆะคงที่สาธารณะ main (String [] args) {
6. สร้างอ็อบเจ็กต์ PrimeGenerator และเริ่มเธรด รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
งานเธรด = PrimeGenerator ใหม่ ();
งาน.เริ่มต้น();
7. รอห้าวินาทีแล้วจึงยุติเธรด รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
พยายาม {
TimeUnit.SECONDS.sleep(5L);
} จับ (InterruptedException e) {
e.printStackTrace();
-
งานขัดจังหวะ ();
8. รันตัวอย่างและดูผลลัพธ์
รู้ว่าทำไม
ด้านล่างนี้คือตัวอย่างการทำงานของโปรแกรมตัวอย่าง จากอักขระที่พิมพ์ออกมา เราจะเห็นว่าเธรด PrimeGenerator พิมพ์ข้อมูลอย่างไร และวิธียุติการดำเนินการเมื่อตรวจพบว่าเธรดถูกขัดจังหวะ
คัดลอกรหัสรหัสดังต่อไปนี้:
หมายเลข 43063 คือ ไพรม์.
หมายเลข 43067 คือ ไพรม์.
หมายเลข 43093 คือ ไพรม์.
หมายเลข 43103 คือ นายกรัฐมนตรี
หมายเลข 43117 คือ นายกรัฐมนตรี
Prime Generator ถูกขัดจังหวะ
เธรดมีฟังก์ชันบูลีนเพื่อระบุว่าเธรดถูกขัดจังหวะหรือไม่ เมื่อเรียกใช้เมธอด Interrupt() จะถูกตั้งค่าเป็นจริง isInterrupted() วิธีการส่งกลับค่าปัจจุบันของทรัพย์สิน
ไม่มีวันสิ้นสุด
เธรดยังมีวิธีการตรวจสอบว่าเธรดถูกขัดจังหวะหรือไม่: วิธีการคงที่ขัดจังหวะ () ซึ่งสามารถตรวจสอบว่าเธรดที่ดำเนินการอยู่ในปัจจุบันถูกขัดจังหวะหรือไม่
คัดลอกรหัสรหัสดังต่อไปนี้:
มีความแตกต่างอย่างมากระหว่างเมธอด isInterrupted() และเมธอด Interrupted() แบบแรกจะไม่เปลี่ยนค่าคุณสมบัติของเธรดว่าถูกขัดจังหวะหรือไม่ ในขณะที่แบบหลังสามารถตั้งค่าเป็นเท็จได้ Interrupted() เป็นวิธีการแบบคงที่ ขอแนะนำให้ใช้เมธอด isInterrupted() สำหรับการพัฒนารายวัน
ตามที่กล่าวไว้ก่อนหน้านี้ เธรดสามารถละเว้นคำขอขัดจังหวะและดำเนินการต่อไปได้ อย่างไรก็ตาม นี่ไม่ใช่ผลลัพธ์ที่เราต้องการ
ใช้หลักคำสอน
บทความนี้แปลมาจาก "Java 7 Concurrency Cookbook" (D Gua Ge ขโมยมาในชื่อ "Java7 Concurrency Example Collection") และใช้เป็นสื่อการเรียนรู้เท่านั้น ห้ามนำไปใช้เพื่อวัตถุประสงค์ทางการค้าใดๆ โดยไม่ได้รับอนุญาต
ความสำเร็จเล็กๆ น้อยๆ
โค้ดทั้งหมดที่ใช้ในโปรแกรมตัวอย่างเวอร์ชันสมบูรณ์
รหัสที่สมบูรณ์ของคลาส PrimeGenerator มีดังนี้:
แพ็คเกจ com.diguage.books.concurrencycookbook.chapter1.recipe3;
-
* วันที่: 18-09-2556
* เวลา: 11:53 น
-
PrimeGenerator ระดับสาธารณะขยายเธรด {
@แทนที่
โมฆะสาธารณะวิ่ง () {
ตัวเลขยาว = 1L;
ในขณะที่ (จริง) {
ถ้า (isPrime (หมายเลข)) {
System.out.printf("หมายเลข %d /tis Prime./n", หมายเลข);
-
ถ้า (ถูกขัดจังหวะ ()) {
System.out.println("ตัวสร้างนายกรัฐมนตรีถูกขัดจังหวะ");
กลับ;
-
หมายเลข++;
-
-
-
* พิจารณาว่าพารามิเตอร์เป็นจำนวนเฉพาะหรือไม่
-
* @param number ตัวเลขที่จะตัดสิน
* @กลับ
-
บูลีนส่วนตัว isPrime (ตัวเลขยาว) {
ถ้า (หมายเลข <= 2) {
กลับเป็นจริง;
-
สำหรับ (int i = 2; i < หมายเลข; i++) {
ถ้า ((จำนวน % i) == 0) {
กลับเท็จ;
-
-
กลับเป็นจริง;
-
-
รหัสที่สมบูรณ์ของคลาสหลัก
คัดลอกรหัสรหัสดังต่อไปนี้:
แพ็คเกจ com.diguage.books.concurrencycookbook.chapter1.recipe3;
นำเข้า java.util.concurrent.TimeUnit;
-
* วันที่: 18-09-2556
* เวลา: 12:33 น
-
ชั้นเรียนสาธารณะหลัก {
โมฆะคงที่สาธารณะ main (String [] args) {
งานเธรด = PrimeGenerator ใหม่ ();
งาน.เริ่มต้น();
พยายาม {
TimeUnit.SECONDS.sleep(5L);
} จับ (InterruptedException e) {
e.printStackTrace();
-
งานขัดจังหวะ ();
-
-