Ben bekleneceği JVM incelikle kesmeler ( thread.interrupt()) en az sinyalleri için uygulama tarafından oluşturulan tüm çalışan iş parçacığı, SIGINT (kill -2)ve SIGTERM (kill -15).
Bu şekilde, sinyal onlara iletilecek ve standart yollarla zarif bir şekilde iş parçacığı iptaline ve kaynak sonlandırmasına izin verecektir .
Ama bu durum böyle değil benim JVM uygulanmasında en az (: Java(TM) SE Runtime Environment (build 1.8.0_25-b17), Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode).
Diğer kullanıcıların yorumladığı gibi, kapatma kancalarının kullanılması zorunlu görünüyor.
Peki bununla nasıl başa çıkacağım?
Öncelikle, bunu tüm programlarda umursamıyorum, sadece kullanıcı iptallerini ve beklenmedik sonları takip etmek istediğim programlarda. Örneğin, java programınızın başkaları tarafından yönetilen bir süreç olduğunu hayal edin. Nazikçe ( SIGTERMyönetici işleminden) sonlandırılmış mı yoksa bir kapanma mı (işi başlangıçta otomatik olarak yeniden başlatmak için) ayırt etmek isteyebilirsiniz .
Temel olarak, uzun süredir devam eden iş parçacıklarımı her zaman kesintiye uğramış durumdan periyodik olarak haberdar InterruptedExceptionediyorum ve kesildiyse bir atıyorum . Bu, geliştirici tarafından kontrol edilen şekilde yürütmenin tamamlanmasını sağlar (ayrıca standart engelleme işlemleriyle aynı sonucu üretir). Ardından, iplik istifinin en üst seviyesinde InterruptedExceptionyakalanır ve uygun temizlik gerçekleştirilir. Bu iş parçacıkları, bir kesinti talebine nasıl yanıt verileceğini bilecek şekilde kodlanmıştır. Yüksek uyum tasarımı.
Bu nedenle, bu durumlarda, JVM'nin varsayılan olarak yapması gerektiğini düşündüğüm şeyi yapan bir kapatma kancası ekliyorum: uygulamam tarafından oluşturulan ve hala çalışan tüm arka plan programı olmayan iş parçacıklarını kes:
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'da test uygulamasını tamamlayın: https://github.com/idelvall/kill-test
kill -9benim için şu anlama geliyor: "Defol, faul süreci, senden uzaklaş!", bunun üzerine sürecin sona ereceği. Hemen.