ฉันคาดหวังว่า JVM จะขัดจังหวะ ( thread.interrupt()
) เธรดที่กำลังทำงานอยู่ทั้งหมดที่สร้างโดยแอปพลิเคชันอย่างสง่างามอย่างน้อยสำหรับสัญญาณSIGINT (kill -2)
และSIGTERM (kill -15)
.
วิธีนี้สัญญาณจะถูกส่งต่อไปพวกเขาช่วยให้มีการยกเลิกด้ายอย่างสง่างามและการสรุปทรัพยากรในรูปแบบมาตรฐาน
แต่นี่ไม่ใช่กรณี (อย่างน้อยในการใช้งาน JVM ของฉัน: Java(TM) SE Runtime Environment (build 1.8.0_25-b17), Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
.
ตามที่ผู้ใช้รายอื่นแสดงความคิดเห็นการใช้ตะขอปิดระบบดูเหมือนจะบังคับ
แล้วฉันจะจัดการยังไงดี?
ก่อนอื่นฉันไม่สนใจมันในทุกโปรแกรมเฉพาะในโปรแกรมที่ฉันต้องการติดตามการยกเลิกของผู้ใช้และการสิ้นสุดที่ไม่คาดคิด ตัวอย่างเช่นสมมติว่าโปรแกรม java ของคุณเป็นกระบวนการที่จัดการโดยโปรแกรมอื่น ๆ คุณอาจต้องการแยกความแตกต่างว่ามีการยกเลิกอย่างไม่เป็นธรรม ( SIGTERM
จากกระบวนการจัดการ) หรือเกิดการปิดระบบ (เพื่อเปิดใช้งานใหม่โดยอัตโนมัติเมื่อเริ่มต้น)
โดยพื้นฐานแล้วฉันมักจะทำให้เธรดที่ใช้งานยาวนานของฉันรับรู้ถึงสถานะที่ถูกขัดจังหวะเป็นระยะ ๆ และInterruptedException
หากพวกเขาถูกขัดจังหวะ สิ่งนี้เปิดใช้งานการสรุปผลการดำเนินการในลักษณะที่ควบคุมโดยนักพัฒนา (ให้ผลลัพธ์เช่นเดียวกับการดำเนินการบล็อกมาตรฐาน) จากนั้นที่ระดับบนสุดของสแต็กเธรดInterruptedException
จะถูกจับและดำเนินการล้างข้อมูลที่เหมาะสม เธรดเหล่านี้ได้รับการเข้ารหัสเพื่อให้ทราบว่าจะตอบสนองต่อคำร้องขอหยุดชะงักได้อย่างไร การออกแบบการทำงานร่วมกันสูง
ดังนั้นในกรณีเหล่านี้ฉันเพิ่ม hook การปิดระบบซึ่งจะทำสิ่งที่ฉันคิดว่า JVM ควรทำตามค่าเริ่มต้น: ขัดจังหวะเธรดที่ไม่ใช่ daemon ทั้งหมดที่สร้างโดยแอปพลิเคชันของฉันที่ยังทำงานอยู่:
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.out.println("Interrupting threads");
Set<Thread> runningThreads = Thread.getAllStackTraces().keySet();
for (Thread th : runningThreads) {
if (th != Thread.currentThread()
&& !th.isDaemon()
&& th.getClass().getName().startsWith("org.brutusin")) {
System.out.println("Interrupting '" + th.getClass() + "' termination");
th.interrupt();
}
}
for (Thread th : runningThreads) {
try {
if (th != Thread.currentThread()
&& !th.isDaemon()
&& th.isInterrupted()) {
System.out.println("Waiting '" + th.getName() + "' termination");
th.join();
}
} catch (InterruptedException ex) {
System.out.println("Shutdown interrupted");
}
}
System.out.println("Shutdown finished");
}
});
กรอกใบสมัครทดสอบที่ github: https://github.com/idelvall/kill-test
kill -9
หมายถึงฉัน: "เริ่มต้นกระบวนการที่ไม่ดีออกไปกับเจ้า!" ซึ่งกระบวนการนี้จะหยุดลง ทันที