เหตุใดจึงเรียกใช้วิธีการThread.currentThread.interrupt()
ใน catch block
เหตุใดจึงเรียกใช้วิธีการThread.currentThread.interrupt()
ใน catch block
คำตอบ:
นี้จะทำเพื่อให้รัฐ
เมื่อคุณจับInterruptException
และกลืนคุณจะต้องป้องกันวิธีการ / กลุ่มเธรดในระดับที่สูงขึ้นจากการสังเกตเห็นการขัดจังหวะ ซึ่งอาจทำให้เกิดปัญหา
โดยการโทร Thread.currentThread().interrupt()
คุณตั้งค่าสถานะอินเตอร์รัปต์ของเธรดดังนั้นตัวจัดการอินเตอร์รัปต์ระดับที่สูงกว่าจะสังเกตเห็นและสามารถจัดการได้อย่างเหมาะสม
Java Concurrency ในการปฏิบัติกล่าวถึงในรายละเอียดในบทที่ 7.1.3: การตอบสนองต่อการหยุดชะงัก กฎของมันคือ:
รหัสเท่านั้นที่ใช้นโยบายการขัดจังหวะของเธรดอาจกลืนคำขอการขัดจังหวะ งานเอนกประสงค์และรหัสห้องสมุดไม่ควรกลืนคำขอขัดจังหวะ
interrupt()
โทรเป็นวิธีเดียวในการตั้งค่าสถานะที่ถูกขัดจังหวะเมื่อคุณได้รับการแจ้งเตือนเกี่ยวกับสถานะนี้ผ่าน "กลไกการจัดส่ง" อื่น ๆ - InterruptedException
และต้องการหรือไม่สามารถโยนทิ้งได้
ฉันคิดว่าตัวอย่างโค้ดนี้ทำให้สิ่งต่าง ๆ ชัดเจน ชั้นเรียนซึ่งทำงาน:
public class InterruptedSleepingThread extends Thread {
@Override
public void run() {
doAPseudoHeavyWeightJob();
}
private void doAPseudoHeavyWeightJob() {
for (int i=0;i<Integer.MAX_VALUE;i++) {
//You are kidding me
System.out.println(i + " " + i*2);
//Let me sleep <evil grin>
if(Thread.currentThread().isInterrupted()) {
System.out.println("Thread interrupted\n Exiting...");
break;
}else {
sleepBabySleep();
}
}
}
/**
*
*/
protected void sleepBabySleep() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
ชั้นหลัก:
public class InterruptedSleepingThreadMain {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
InterruptedSleepingThread thread = new InterruptedSleepingThread();
thread.start();
//Giving 10 seconds to finish the job.
Thread.sleep(10000);
//Let me interrupt
thread.interrupt();
}
}
ลองโทรขัดจังหวะโดยไม่ตั้งสถานะกลับ
บันทึก:
ฉันจะหยุดเธรดที่รอเป็นเวลานานได้อย่างไร (เช่นสำหรับอินพุต)
เพื่อให้เทคนิคนี้ใช้งานได้เป็นสิ่งสำคัญที่วิธีการใดก็ตามที่จับข้อยกเว้นขัดจังหวะและไม่ได้เตรียมที่จะจัดการกับข้อยกเว้นนั้นทันที เราพูดว่า reasserts มากกว่า rethrows เพราะมันเป็นไปไม่ได้เสมอที่จะทำการยกเว้นใหม่ หากวิธีการที่จับ InterruptException ไม่ได้ประกาศว่าจะโยนข้อยกเว้น (ตรวจสอบ) นี้ก็ควร "reinterrupt ตัวเอง" ด้วยคาถาต่อไปนี้:
Thread.currentThread().interrupt();
สิ่งนี้ช่วยให้มั่นใจได้ว่าเธรดจะทำการ InterruptException ทันทีที่สามารถทำได้
ฉันคิดว่ามันเป็นการปฏิบัติที่ไม่ดีหรืออย่างน้อยก็มีความเสี่ยง โดยปกติแล้ววิธีการระดับสูงกว่าจะไม่ทำการบล็อกและจะไม่เห็นInterruptedException
หยุด หากคุณปิดบังไว้ในทุกที่ที่คุณทำการดำเนินการขัดจังหวะคุณจะไม่ได้รับมัน
เหตุผลเดียวที่Thread.currentThread.interrupt()
ทำให้ไม่ยกข้อยกเว้นอื่น ๆ หรือส่งสัญญาณคำขอขัดจังหวะด้วยวิธีอื่น ๆ (เช่นการตั้งค่าinterrupted
ตัวแปรตัวแปรท้องถิ่นในลูปหลักของเธรด) คือสถานการณ์ที่คุณไม่สามารถทำสิ่งใดด้วยข้อยกเว้นเช่นในfinally
บล็อก
ดูคำตอบของPéterTörökหากคุณต้องการเข้าใจความหมายของการThread.currentThread.interrupt()
โทร
อ้างอิงจาก java doc
หากเธรดนี้ถูกบล็อกในการเรียกใช้การรอ (), เข้าร่วม (), สลีป (ยาว) จากนั้นสถานะการขัดจังหวะของมันจะถูกล้างและจะได้รับการขัดจังหวะ
ถ้าเธรดนี้ถูกบล็อกในการดำเนินการ I / O สถานะการขัดจังหวะของเธรดจะถูกตั้งค่าและเธรดจะได้รับ ClosedByInterruptException
หากเธรดนี้ถูกบล็อกในตัวเลือกสถานะการขัดจังหวะของเธรดจะถูกตั้งค่าและมันจะกลับมาทันทีจากการดำเนินการเลือก
หากไม่มีเงื่อนไขก่อนหน้านี้ค้างไว้สถานะขัดจังหวะของเธรดนี้จะถูกตั้งค่า
ดังนั้นหากคุณเปลี่ยนวิธี sleepBabySleep () ในการดำเนินการ @Ajay George Answer to I / O หรือเพียงแค่ sysout คุณไม่จำเป็นต้องตั้งสถานะกลับเพื่อหยุดโปรแกรม (BTW พวกเขาไม่ได้โยนการขัดจังหวะด้วยข้อยกเว้น)
เช่นเดียวกับ @ PéterTörökพูดว่า => สิ่งนี้ทำเพื่อรักษาสถานะ (และโดยเฉพาะอย่างยิ่งสำหรับวิธีการที่จะทำให้เกิดการขัดจังหวะยกเว้น)
InterruptedException
สถานะขัดจังหวะที่ชัดเจนเมื่อทำเช่นนั้นฉันคิดว่านี่จะทำให้คำตอบชัดเจนขึ้นในแง่ของสาเหตุที่คุณต้องรักษาสถานะการขัดจังหวะ