การจัดการ InterruptedException ใน Java


317

ความแตกต่างระหว่างวิธีการจัดการต่อไปนี้InterruptedExceptionคืออะไร? วิธีที่ดีที่สุดที่จะทำคืออะไร?

try{
 //...
} catch(InterruptedException e) { 
   Thread.currentThread().interrupt(); 
}

หรือ

try{
 //...
} catch(InterruptedException e) {
   throw new RuntimeException(e);
}

แก้ไข: ฉันต้องการที่จะรู้ว่าในสถานการณ์เหล่านี้ใช้ทั้งสอง


คำตอบ:


436

ความแตกต่างระหว่างวิธีการจัดการ 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และคุณควร (ต้อง!) ตรวจจับข้อยกเว้น ตอนนี้มีสองสิ่งที่สำคัญที่ต้องจำไว้ในสถานการณ์นี้:

    1. มีคนขัดจังหวะชุดข้อความของคุณ อาจมีบางคนที่อยากจะยกเลิกการดำเนินการยกเลิกโปรแกรมอย่างสง่างามหรืออะไรก็ตาม คุณควรจะสุภาพกับใครคนนั้นและกลับมาจากวิธีการของคุณโดยไม่ต้องกังวลใจต่อไป

    2. แม้ว่าวิธีการของคุณสามารถจัดการเพื่อสร้างมูลค่าส่งคืนที่เหมาะสมในกรณี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;
}

โพสต์นี้ได้รับการเขียนใหม่เป็นบทความที่นี่


ปัญหาของวิธีที่สองคืออะไร
blitzkriegz

4
บทความกล่าวว่าคุณควรโทรinterrupt()เพื่อรักษาสถานะถูกขัดจังหวะ อะไรคือเหตุผลที่อยู่เบื้องหลังไม่ได้ทำนี้บนThread.sleep()?
oksayt

7
ฉันไม่เห็นด้วยในกรณีที่เธรดของคุณไม่รองรับการขัดจังหวะการขัดจังหวะใด ๆ ที่ได้รับจะบ่งบอกถึงเงื่อนไขที่ไม่คาดคิด (เช่นข้อผิดพลาดในการเขียนโปรแกรมการใช้ API ที่ไม่ดี) และการประกันตัวออกมาด้วย RuntimeException เป็นการตอบสนองที่เหมาะสม ) นอกจากจะถือว่าเป็นส่วนหนึ่งของสัญญาทั่วไปของเธรดแม้ว่าคุณจะไม่สนับสนุนการขัดจังหวะคุณต้องดำเนินการต่อเมื่อคุณได้รับ
อะมี

12
วิธีการโทรที่ทำให้เกิด InterruptExceptions และบอกว่าคุณ "ไม่รองรับการขัดจังหวะ" ดูเหมือนว่าการเขียนโปรแกรมเลอะเทอะและมีบั๊กรอเกิดขึ้น ใส่แตกต่างกัน ถ้าคุณเรียกใช้วิธีการที่ประกาศว่าจะโยน InterruptedException ไม่ควรเป็นเงื่อนไขที่ไม่คาดคิดหากวิธีการนั้นจริง ๆ แล้วโยนข้อยกเว้นดังกล่าว
aioobe

1
@MartiNito ไม่เรียกร้องThread.currentThread.interrupt()ในInterruptedExceptionการป้องกันการจับจะตั้งค่าได้เพียงธงขัดจังหวะ มันจะไม่ทำให้ผู้อื่นInterruptedExceptionถูกโยน / ถูกจับในInterruptedExceptionบล็อก catch ภายนอก
aioobe

97

เมื่อมันเกิดขึ้นฉันเพิ่งอ่านเกี่ยวกับเรื่องนี้เมื่อเช้านี้เพื่อไปทำงานในJava Concurrency In Practiceโดย Brian Goetz โดยทั่วไปเขาบอกว่าคุณควรทำหนึ่งในสามสิ่งนี้

  1. เผยแพร่InterruptedException - ประกาศวิธีการของคุณที่จะโยนการตรวจสอบInterruptedExceptionเพื่อให้โทรของคุณต้องจัดการกับมัน

  2. เรียกคืนขัดจังหวะ - InterruptedExceptionบางครั้งคุณไม่สามารถโยน ในกรณีเหล่านี้คุณควรตรวจจับInterruptedExceptionและเรียกคืนสถานะอินเตอร์รัปต์โดยการเรียกใช้interrupt()เมธอดcurrentThreadเพื่อให้โค้ดที่สูงขึ้นสแต็คการโทรสามารถเห็นว่ามีการออกอินเทอร์รัปต์และส่งคืนจากเมธอดอย่างรวดเร็ว หมายเหตุ: วิธีนี้ใช้ได้เฉพาะเมื่อวิธีการของคุณมีความหมาย "ลอง" หรือ "พยายามอย่างดีที่สุด" นั่นคือไม่มีอะไรสำคัญหากวิธีการไม่บรรลุเป้าหมาย ยกตัวอย่างเช่นlog()หรือsendMetric()อาจจะเป็นวิธีการดังกล่าวหรือแต่ไม่boolean tryTransferMoney() void transferMoney()ดูที่นี่สำหรับรายละเอียดเพิ่มเติม

  3. ละเว้นการหยุดชะงักภายในวิธี แต่เรียกคืนสถานะเมื่อออก - Uninterruptiblesเช่นผ่านทางฝรั่งของ Uninterruptiblesรับรหัสสำเร็จรูปในตัวอย่างงานที่ไม่สามารถยกเลิกได้ใน JCIP § 7.1.3

10
"บางครั้งคุณไม่สามารถโยนการขัดจังหวะด้วยข้อยกเว้น" - ฉันจะบอกว่าบางครั้งมันไม่เหมาะสำหรับวิธีการโพสต์การขัดจังหวะข้อยกเว้น สูตรของคุณดูเหมือนว่าจะแนะนำว่าคุณควรจะ rethrow InterruptedException เมื่อใดก็ตามที่คุณสามารถ
aioobe

1
และถ้าคุณต้องอ่านบทที่ 7 คุณจะเห็นว่ามีรายละเอียดปลีกย่อยเช่นนี้ในรายการ 7.7 ซึ่งเป็นภารกิจที่ไม่สามารถยกเลิกได้ไม่สามารถคืนค่าการขัดจังหวะได้ทันทีแต่หลังจากเสร็จสิ้น นอกจากนี้ยังเก๊มีผู้เขียนร่วมจำนวนมากเพื่อหนังสือที่ ...
ฟอง

1
ฉันชอบคำตอบของคุณเพราะมันกระชับ แต่ฉันเชื่อว่ามันควรจะพูดเบา ๆ และกลับอย่างรวดเร็วจากฟังก์ชั่นของคุณในกรณีที่สอง ลองนึกภาพลูป (หรืออนันต์) แบบยาวที่มี Thread.sleep () อยู่ตรงกลาง การจับของ InterruptedException ควรเรียก Thread.currentThread (). interrupt () และแยกออกจากลูป
Yann Vo

@YannVo ฉันได้แก้ไขคำตอบเพื่อใช้คำแนะนำของคุณ
leventov

18

คุณพยายามจะทำอะไร?

InterruptedExceptionจะถูกโยนทิ้งเมื่อด้ายคือการรอคอยหรือนอนและขัดจังหวะหัวข้ออื่นโดยใช้วิธีการในชั้นเรียนinterrupt Threadดังนั้นหากคุณตรวจพบข้อยกเว้นนี้แสดงว่าเธรดถูกขัดจังหวะ มักจะไม่มีจุดในการโทรThread.currentThread().interrupt();อีกครั้งเว้นแต่ว่าคุณต้องการตรวจสอบสถานะ "ขัดจังหวะ" ของเธรดจากที่อื่น

เกี่ยวกับตัวเลือกอื่นในการขว้าง a RuntimeExceptionดูเหมือนว่าจะไม่ฉลาดนัก (ใครจะเป็นผู้จับสิ่งนี้จะจัดการอย่างไร) แต่เป็นการยากที่จะบอกเพิ่มเติมโดยไม่มีข้อมูลเพิ่มเติม


14
การโทรThread.currentThread().interrupt()ตั้งค่าการขัดจังหวะ (อีกครั้ง) ซึ่งมีประโยชน์แน่นอนถ้าเราต้องการให้แน่ใจว่าการขัดจังหวะได้รับการสังเกตและประมวลผลในระดับที่สูงขึ้น
PéterTörök

1
@ ปีเตอร์: ฉันเพิ่งจะอัพเดตคำตอบเพื่อพูดถึงเรื่องนี้ ขอบคุณ
Grodriguez

12

สำหรับฉันสิ่งสำคัญเกี่ยวกับเรื่องนี้คือ: การขัดจังหวะโดยไม่มีข้อยกเว้นจะเกิดอะไรขึ้นมันเป็นด้ายทำสิ่งที่คุณบอกให้ทำ ดังนั้นการคำนวณใหม่อีกครั้งในโปรแกรม RuntimeException จึงไม่มีเหตุผล

ในหลายกรณีมันเหมาะสมที่จะรื้อฟื้นข้อยกเว้นที่ห่อไว้ใน RuntimeException เมื่อคุณพูดว่าฉันไม่รู้ว่ามีอะไรผิดพลาดที่นี่และฉันไม่สามารถทำอะไรเพื่อแก้ไขได้ฉันแค่อยากให้มันออกจากกระแสการประมวลผล และกดตัวจัดการข้อยกเว้นทั่วทั้งแอปพลิเคชันใดก็ตาม นั่นไม่ใช่กรณีที่มี InterruptException แต่เป็นเพียงเธรดที่ตอบสนองต่อการถูกขัดจังหวะ () เรียกใช้มันกำลังส่ง InterruptException เพื่อช่วยยกเลิกการประมวลผลของเธรดในเวลาที่เหมาะสม

ดังนั้นเผยแพร่ InterruptException หรือกินมันอย่างชาญฉลาด (หมายถึงสถานที่ที่มันจะทำสิ่งที่มันตั้งใจจะทำ) และตั้งค่าการขัดจังหวะ โปรดทราบว่าการตั้งค่าอินเตอร์รัปต์จะถูกล้างเมื่อ InterruptException ถูกส่งออกไป สมมติฐานที่นักพัฒนาไลบรารี Jdk ทำคือการจับจำนวนข้อยกเว้นเพื่อจัดการมัน

ดังนั้นวิธีแรกจะดีกว่าตัวอย่างที่สองที่โพสต์ในคำถามนั้นไม่มีประโยชน์เว้นแต่คุณจะไม่คาดหวังว่าเธรดจะถูกขัดจังหวะจริง ๆ

นี่คือคำตอบที่ผมเขียนอธิบายถึงวิธีการทำงานการขัดจังหวะด้วยตัวอย่าง คุณสามารถเห็นในตัวอย่างรหัสที่ใช้ InterruptedException เพื่อประกันตัวออกจากในขณะที่ห่วงในวิธีการเรียกใช้ของ Runnable


10

ตัวเลือกเริ่มต้นที่ถูกต้องคือเพิ่ม InterruptedException ให้กับรายการการส่งของคุณ การขัดจังหวะเป็นการระบุว่าเธรดอื่นต้องการให้เธรดของคุณสิ้นสุด เหตุผลสำหรับคำขอนี้ไม่ปรากฏชัดเจนและเป็นบริบททั้งหมดดังนั้นหากคุณไม่มีความรู้เพิ่มเติมคุณควรถือว่าเป็นเพียงการปิดระบบที่เป็นมิตรและสิ่งใดก็ตามที่หลีกเลี่ยงการปิดระบบนั้นเป็นการตอบสนองที่ไม่เป็นมิตร

Java จะไม่สุ่มโยน InterruptedException คำแนะนำทั้งหมดจะไม่ส่งผลกระทบต่อแอปพลิเคชันของคุณ แต่ฉันได้พบกับกรณีที่ผู้พัฒนาติดตามกลยุทธ์ "กลืน" ไม่สะดวก ทีมได้พัฒนาชุดการทดสอบจำนวนมากและใช้ Thread.Sleep มาก ตอนนี้เราเริ่มทำการทดสอบในเซิร์ฟเวอร์ CI ของเราและบางครั้งเนื่องจากข้อบกพร่องในรหัสจะติดอยู่ในการรอถาวร เพื่อทำให้สถานการณ์แย่ลงเมื่อพยายามที่จะยกเลิกงาน CI มันไม่เคยปิดเพราะ Thread.Interrupt ที่ตั้งใจจะยกเลิกการทดสอบไม่ได้ยกเลิกงาน เราต้องเข้าสู่กล่องและฆ่ากระบวนการด้วยตนเอง

เรื่องสั้นยาวสั้นหากคุณเพียงแค่โยน InterruptedException คุณกำลังจับคู่เจตนาเริ่มต้นที่เธรดของคุณควรจะจบลง หากคุณไม่สามารถเพิ่ม InterruptedException ลงในรายการการโยนของคุณฉันจะสรุปใน RuntimeException

มีข้อโต้แย้งที่สมเหตุสมผลที่จะทำให้ InterruptException ควรเป็น RuntimeException ด้วยตัวเองเพราะนั่นจะสนับสนุนการจัดการ "ค่าเริ่มต้น" ที่ดีกว่า ไม่ใช่ RuntimeException เท่านั้นเนื่องจากผู้ออกแบบติดอยู่กับกฎเด็ดขาดที่ RuntimeException ควรแสดงถึงข้อผิดพลาดในรหัสของคุณ เนื่องจาก InterruptedException ไม่ได้เกิดขึ้นโดยตรงจากข้อผิดพลาดในรหัสของคุณจึงไม่ใช่ แต่ความจริงก็คือบ่อยครั้งที่ InterruptedException เกิดขึ้นเนื่องจากมีข้อผิดพลาดในรหัสของคุณ (เช่นวนซ้ำไม่รู้จบล็อคตาย) และ Interrupt เป็นวิธีการอื่นของเธรดเพื่อจัดการกับข้อผิดพลาดนั้น

หากคุณรู้ว่ามีการล้างข้อมูลด้วยเหตุผลให้ทำ หากคุณทราบสาเหตุที่ลึกกว่าสำหรับการขัดจังหวะคุณสามารถจัดการได้อย่างครอบคลุมมากขึ้น

ดังนั้นโดยสรุปตัวเลือกของคุณสำหรับการจัดการควรเป็นไปตามรายการนี้:

  1. โดยค่าเริ่มต้นเพิ่มไปที่การโยน
  2. หากไม่ได้รับอนุญาตให้เพิ่มไปยัง Throws ให้ใช้ RuntimeException (e) (ตัวเลือกที่ดีที่สุดของตัวเลือกที่ไม่ดีหลายตัว)
  3. เฉพาะเมื่อคุณทราบสาเหตุที่ชัดเจนของการขัดจังหวะจัดการตามที่ต้องการ หากการจัดการของคุณเป็นแบบท้องถิ่นกับวิธีการของคุณแล้วรีเซ็ตการขัดจังหวะโดยการเรียกไปที่ Thread.currentThread (). interrupt ()

3

ฉันแค่อยากจะเพิ่มหนึ่งตัวเลือกสุดท้ายในสิ่งที่คนส่วนใหญ่และบทความพูดถึง ตามที่ mR_fr0g ได้ระบุไว้สิ่งสำคัญคือการจัดการการขัดจังหวะอย่างถูกต้องโดย:

  • การแพร่กระจาย InterruptException

  • กู้คืนสถานะอินเตอร์รัปต์บนเธรด

หรือนอกจากนี้:

  • การจัดการ Interrupt แบบกำหนดเอง

ไม่มีอะไรผิดปกติในการจัดการกับการขัดจังหวะในวิธีที่กำหนดขึ้นอยู่กับสถานการณ์ของคุณ เนื่องจากอินเทอร์รัปต์เป็นการร้องขอการยกเลิกซึ่งตรงข้ามกับคำสั่งที่มีพลังจึงสามารถใช้งานได้อย่างสมบูรณ์เพื่อให้แอปพลิเคชันจัดการคำขอได้อย่างสมบูรณ์ ตัวอย่างเช่นหากเธรดกำลังนอนหลับกำลังรอ IO หรือการตอบกลับของฮาร์ดแวร์เมื่อได้รับการขัดจังหวะจากนั้นจะมีผลสมบูรณ์เมื่อปิดการเชื่อมต่อใด ๆ ก่อนที่จะยกเลิกเธรด

ฉันขอแนะนำให้ทำความเข้าใจกับหัวข้อ แต่บทความนี้เป็นแหล่งข้อมูลที่ดี: http://www.ibm.com/developerworks/java/library/j-jtp05236/


0

ฉันจะบอกว่าในบางกรณีมันก็โอเคที่จะไม่ทำอะไรเลย อาจไม่ใช่สิ่งที่คุณควรทำตามค่าเริ่มต้น แต่ในกรณีที่ไม่มีวิธีการขัดจังหวะที่จะเกิดขึ้นฉันไม่แน่ใจว่าจะต้องทำอะไรอีก (อาจจะเกิดข้อผิดพลาดในการบันทึก

กรณีหนึ่งจะเป็นในกรณีที่คุณมีคิวงาน (บล็อก) ในกรณีที่คุณมี daemon Thread ที่จัดการงานเหล่านี้และคุณไม่รบกวน Thread ด้วยตัวเอง (จากความรู้ของฉัน jvm จะไม่ขัดจังหวะ daemon เธรดในการปิด jvm) ฉันไม่เห็นวิธีที่จะเกิดการขัดจังหวะและดังนั้นจึงอาจ เพียงแค่ละเว้น (ฉันรู้ว่าเธรด daemon อาจถูกฆ่าโดย jvm เมื่อใดก็ได้ดังนั้นจึงไม่เหมาะสมในบางกรณี)

แก้ไข: กรณีอื่นอาจได้รับการปกป้องบล็อกอย่างน้อยตามการสอนของ Oracle ที่: http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html


นี่คือคำแนะนำที่ไม่ดี ฉันมีปัญหาอย่างมากในการคิดงานใด ๆ ที่สำคัญมากที่จะเพิกเฉยต่อการขัดจังหวะ Oracle น่าจะเป็นคนขี้เกียจและไม่ต้องการเพิ่มความยุ่งเหยิงในการเรียกใช้ Thread.sleep () อีก ถ้าคุณไม่ทราบว่าทำไมเธรดของคุณถึงถูกขัดจังหวะคุณควรหยุดสิ่งที่คุณกำลังทำอยู่ (ไม่ว่าจะกลับมาหรือสร้างข้อยกเว้นใหม่เพื่อช่วยให้เธรดของคุณตายเร็วที่สุด)
Ajax

นั่นเป็นเหตุผลที่ฉันพูดบางครั้ง เพราะมันยังไม่ได้รับการแนะนำและมันก็ดีในบางกรณีในความคิดของฉัน ฉันคิดว่ามันขึ้นอยู่กับซอฟต์แวร์ที่คุณกำลังสร้าง แต่ถ้าคุณมีเธรดคนทำงานตลอด 24/7 ที่ไม่ควรหยุด (นอกเหนือจากการปิดตัวลงของ JVM) ฉันจะจัดการกับอินเทอร์รัปต์เช่นการนำไอเท็มจาก BlockingQueue เป็นข้อผิดพลาด (เช่นบันทึก) เนื่องจาก "ไม่ควรเกิดขึ้น" และลองอีกครั้ง ของ cource ฉันจะมีธงแยกต่างหากเพื่อตรวจสอบการยกเลิกโปรแกรม ในบางโปรแกรมของฉันการปิด JVM ไม่ใช่สิ่งที่ควรเกิดขึ้นภายใต้การทำงานปกติ
Bjarne Boström

หรือใส่อีกวิธีหนึ่ง: ในความคิดของฉันมันจะดีกว่าที่จะเสี่ยงต่อการมีงบบันทึกข้อผิดพลาดพิเศษ (และเช่นมีการส่งจดหมายในบันทึกข้อผิดพลาด) กว่ามีแอปพลิเคชันที่ควรจะทำงาน 24/7 เพื่อหยุดเนื่องจาก ฉันไม่เห็นวิธีที่จะเกิดขึ้นในสภาวะปกติ
Bjarne Boström

หืมมกรณีการใช้งานของคุณอาจแตกต่างกัน แต่ในโลกอุดมคติคุณไม่เพียงแค่ยุติเพราะคุณถูกขัดจังหวะ คุณหยุดทำงานนอกคิวและปล่อยให้เธรดนั้นตาย หากตัวกำหนดตารางเวลาของเธรดถูกขัดจังหวะและบอกให้ปิดการทำงานดังนั้น JVM จะถูกยกเลิกและเกมจะจบลง โดยเฉพาะอย่างยิ่งถ้าคุณส่ง kill -9 หรือพยายามที่จะทำลายเมลเซิร์ฟเวอร์ของคุณหรืออะไรก็ตามมันจะไม่สนใจคุณจนกว่าคุณจะบังคับให้ออกดังนั้นการป้องกันส่วนอื่น ๆ ของรหัสของคุณจากการปิดระบบที่สง่างาม บังคับให้ฆ่าขณะเขียนลงดิสก์หรือ db และฉันแน่ใจว่าสิ่งมหัศจรรย์จะเกิดขึ้น
Ajax
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.