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 ( SIGTERM
yö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 InterruptedException
ediyorum 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 InterruptedException
yakalanı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 -9
benim için şu anlama geliyor: "Defol, faul süreci, senden uzaklaş!", bunun üzerine sürecin sona ereceği. Hemen.