ความแตกต่างระหว่างวิธีการจัดการ InterruptedException ต่อไปนี้คืออะไร วิธีที่ดีที่สุดที่จะทำคืออะไร?
คุณอาจมาถามคำถามนี้เพราะคุณเรียกวิธีการInterruptedException
หนึ่ง
ก่อนอื่นคุณควรเห็นthrows InterruptedException
ว่ามันคืออะไร: ส่วนหนึ่งของวิธีการที่เป็นลายเซ็นและผลลัพธ์ที่เป็นไปได้ของการโทรวิธีที่คุณโทร ดังนั้นเริ่มต้นด้วยการยอมรับความจริงที่ว่าInterruptedException
เป็นผลที่สมบูรณ์แบบของการเรียกใช้เมธอด
ทีนี้ถ้าวิธีการที่คุณโทรมีข้อยกเว้นเช่นนั้นวิธีการของคุณควรทำอย่างไร? คุณสามารถหาคำตอบได้โดยคิดถึงสิ่งต่อไปนี้:
มันเหมาะสมสำหรับวิธีการที่คุณใช้ในการโยนInterruptedException
หรือไม่? สิ่งที่แตกต่างกันคือInterruptedException
ผลลัพธ์ที่สมเหตุสมผลเมื่อเรียกใช้วิธีการของคุณ ?
ถ้าใช่แล้วthrows InterruptedException
ควรเป็นส่วนหนึ่งของคุณลายเซ็นวิธีและคุณควรปล่อยให้การเผยแพร่ข้อยกเว้น (เช่นไม่จับมันเลย)
ตัวอย่าง : วิธีการของคุณรอค่าจากเครือข่ายเพื่อให้การคำนวณเสร็จสิ้นและส่งคืนผลลัพธ์ หากการบล็อกเครือข่ายโทรออกInterruptedException
วิธีการของคุณไม่สามารถคำนวณได้ตามปกติ คุณปล่อยให้การInterruptedException
เผยแพร่
int computeSum(Server server) throws InterruptedException {
// Any InterruptedException thrown below is propagated
int a = server.getValueA();
int b = server.getValueB();
return a + b;
}
ถ้าไม่เช่นนั้นคุณไม่ควรประกาศวิธีการของคุณด้วยthrows InterruptedException
และคุณควร (ต้อง!) ตรวจจับข้อยกเว้น ตอนนี้มีสองสิ่งที่สำคัญที่ต้องจำไว้ในสถานการณ์นี้:
มีคนขัดจังหวะชุดข้อความของคุณ อาจมีบางคนที่อยากจะยกเลิกการดำเนินการยกเลิกโปรแกรมอย่างสง่างามหรืออะไรก็ตาม คุณควรจะสุภาพกับใครคนนั้นและกลับมาจากวิธีการของคุณโดยไม่ต้องกังวลใจต่อไป
แม้ว่าวิธีการของคุณสามารถจัดการเพื่อสร้างมูลค่าส่งคืนที่เหมาะสมในกรณีInterruptedException
ที่ความจริงที่ว่าเธรดถูกขัดจังหวะอาจยังคงมีความสำคัญ โดยเฉพาะอย่างยิ่งรหัสที่เรียกวิธีการของคุณอาจสนใจว่าเกิดการขัดจังหวะระหว่างการดำเนินการตามวิธีการของคุณหรือไม่ คุณควรบันทึกข้อเท็จจริงที่มีการหยุดชะงักโดยการตั้งค่าสถานะขัดจังหวะ:Thread.currentThread().interrupt()
ตัวอย่าง : ผู้ใช้ขอให้พิมพ์ผลรวมของสองค่า การพิมพ์ " Failed to compute sum
" เป็นที่ยอมรับได้หากไม่สามารถคำนวณผลรวมได้ (และดีกว่าปล่อยให้โปรแกรมขัดข้องด้วยการติดตามสแต็กเนื่องจากการInterruptedException
) ในคำอื่น ๆ ก็ไม่ได้throws InterruptedException
ทำให้ความรู้สึกที่จะประกาศวิธีการนี้ด้วย
void printSum(Server server) {
try {
int sum = computeSum(server);
System.out.println("Sum: " + sum);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // set interrupt flag
System.out.println("Failed to compute sum");
}
}
โดยตอนนี้มันควรจะชัดเจนว่าการทำเพียงแค่throw new RuntimeException(e)
เป็นความคิดที่ไม่ดี มันไม่สุภาพมากสำหรับผู้โทร คุณสามารถคิดค้นข้อยกเว้นรันไทม์ใหม่ แต่สาเหตุที่แท้จริง (บางคนต้องการให้เธรดหยุดการทำงาน) อาจหายไป
ตัวอย่างอื่น ๆ :
การนำไปใช้Runnable
: อย่างที่คุณอาจค้นพบลายเซ็นของRunnable.run
ไม่อนุญาตให้ทำการทำInterruptedExceptions
ใหม่ ดีที่คุณลงทะเบียนในการใช้Runnable
ซึ่งหมายความว่าคุณInterruptedExceptions
ได้ลงทะเบียนเพื่อจัดการกับความเป็นไปได้ เลือกอินเทอร์เฟซอื่นเช่นCallable
หรือทำตามวิธีที่สองด้านบน
การโทรThread.sleep
: คุณกำลังพยายามอ่านไฟล์และข้อมูลจำเพาะระบุว่าคุณควรลอง 10 ครั้งโดยใช้เวลา 1 วินาที คุณโทรThread.sleep(1000)
มา InterruptedException
ดังนั้นคุณจำเป็นต้องจัดการกับ สำหรับวิธีการเช่นtryToReadFile
มันทำให้รู้สึกดีที่จะพูดว่า"ถ้าฉันขัดจังหวะฉันไม่สามารถดำเนินการของฉันพยายามที่จะอ่านไฟล์" ในคำอื่น ๆ InterruptedExceptions
ก็จะทำให้ความรู้สึกที่สมบูรณ์แบบสำหรับวิธีการโยน
String tryToReadFile(File f) throws InterruptedException {
for (int i = 0; i < 10; i++) {
if (f.exists())
return readFile(f);
Thread.sleep(1000);
}
return null;
}
โพสต์นี้ได้รับการเขียนใหม่เป็นบทความที่นี่