Tôi mong rằng JVM duyên dáng ngắt (thread.interrupt()
) tất cả các chủ đề chạy tạo ra bởi các ứng dụng, ít nhất là cho tín hiệu SIGINT (kill -2)
và SIGTERM (kill -15)
.
Bằng cách này, tín hiệu sẽ được chuyển tiếp tới chúng, cho phép hủy bỏ chuỗi và xóa tài nguyên một cách duyên dáng trong standard ways.
Nhưng đây không phải là trường hợp (ít nhất là trong việc thực hiện JVM của tôi:.. Java(TM) SE Runtime Environment (build 1.8.0_25-b17), Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
Khi người dùng khác nhận xét, việc sử dụng móc shutdown dường như bắt buộc
Vì vậy, làm thế nào tôi
Trước tiên, tôi không quan tâm đến nó trong tất cả các chương trình, chỉ trong những chương trình mà tôi muốn theo dõi việc hủy người dùng và kết thúc không mong muốn. Ví dụ, hãy tưởng tượng rằng chương trình java của bạn là một người xử lý tuổi khác. Bạn có thể muốn phân biệt xem nó đã được chấm dứt một cách duyên dáng (SIGTERM
từ quá trình quản lý) hay tắt máy đã xảy ra (để khởi động lại tự động công việc khi khởi động).
Là cơ sở, tôi luôn làm cho các chuỗi dài chạy của mình nhận biết được trạng thái bị gián đoạn và ném InterruptedException
nếu chúng bị gián đoạn. Điều này cho phép thực hiện quyết toán theo cách được kiểm soát bởi nhà phát triển (cũng tạo ra kết quả tương tự như các hoạt động chặn chuẩn). Sau đó, ở cấp cao nhất của ngăn xếp luồng, InterruptedException
được chụp và thực hiện dọn sạch thích hợp. Các luồng này được mã hóa để biết cách trả lời yêu cầu gián đoạn. Thiết kế cao cohesion.
Vì vậy, trong những trường hợp này, tôi thêm một cái móc tắt máy, mà những gì tôi nghĩ JVM nên làm theo mặc định: ngắt tất cả các chủ đề phi daemon được tạo ra bởi ứng dụng của tôi vẫn đang chạy:
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");
}
});
Hoàn thành ứng dụng thử nghiệm tại github: https://github.com/idelvall/kill-test
'giết -9' có nghĩa là với tôi:" Bắt đầu, quá trình phạm lỗi, đi với ngươi! ", Khi mà quá trình sẽ chấm dứt. Ngay. – ZoogieZork
Trên hầu hết các * nixes mà tôi biết, kill -9 không thể bị chặn và xử lý một cách duyên dáng bởi bất kỳ chương trình nào dù nó được viết bằng ngôn ngữ nào. –
@Bui: ngoài những gì người khác đã nhận xét và trả lời, * NẾU * Un * x hệ điều hành của bạn không ngay lập tức giết * VÀ ĐĂNG KÝ TẤT CẢ TÀI NGUYÊN * được sử dụng bởi chương trình được * kill -9'ed *, tốt ... Hệ điều hành bị hỏng. – SyntaxT3rr0r