Menambah Cangkuk Penutupan untuk Aplikasi JVM

1. Gambaran keseluruhan

Biasanya memulakan perkhidmatan dengan mudah. Namun, kadang-kadang kita perlu mempunyai rancangan untuk mematikannya.

Dalam tutorial ini, kita akan melihat pelbagai cara aplikasi JVM dapat ditamatkan. Kemudian, kami akan menggunakan Java API untuk menguruskan cangkuk penutupan JVM. Lihat artikel ini untuk mengetahui lebih lanjut tentang mematikan JVM dalam aplikasi Java.

2. Penutupan JVM

JVM boleh ditutup dengan dua cara yang berbeza:

  1. Proses terkawal
  2. Cara tiba-tiba

Proses terkawal mematikan JVM apabila:

  • Benang bukan daemon terakhir berakhir. Contohnya, semasa utas utama keluar, JVM memulakan proses penutupannya
  • Menghantar isyarat gangguan dari OS. Contohnya, dengan menekan Ctrl + C atau keluar dari OS
  • Memanggil System.exit () dari kod Java

Walaupun kita semua berusaha untuk mematikan, kadang-kadang JVM mungkin ditutup secara tiba-tiba dan tidak dijangka. JVM ditutup secara tiba-tiba apabila :

  • Menghantar isyarat bunuh dari OS. Contohnya, dengan mengeluarkan kill -9
  • Memanggil Runtime.getRuntime (). Berhenti () dari kod Java
  • OS hos mati secara tidak dijangka, sebagai contoh, dalam gangguan kuasa atau panik OS

3. Cangkuk Penutupan

JVM membenarkan fungsi pendaftaran berjalan sebelum menyelesaikan penutupannya. Fungsi-fungsi ini biasanya merupakan tempat yang baik untuk melepaskan sumber atau tugas menjaga rumah yang serupa. Dalam terminologi JVM, fungsi-fungsi ini disebut sebagai sangkut hutdown .

Cangkuk tutup pada asasnya adalah benang yang tidak dimulakan tetapi tidak dimulakan . Apabila JVM memulakan proses penutupannya, ia akan memulakan semua kait yang didaftarkan dalam urutan yang tidak ditentukan. Setelah menjalankan semua cangkuk, JVM akan berhenti.

3.1. Menambah Cangkuk

Untuk menambahkan cangkuk penutupan, kita dapat menggunakan kaedah Runtime.getRuntime (). AddShutdownHook () :

Thread printingHook = new Thread(() -> System.out.println("In the middle of a shutdown")); Runtime.getRuntime().addShutdownHook(printingHook);

Di sini kita hanya mencetak sesuatu ke output standard sebelum JVM ditutup sendiri. Sekiranya kita mematikan JVM seperti berikut:

> System.exit(129); In the middle of a shutdown

Kemudian kita akan melihat bahawa cangkuk benar-benar mencetak mesej ke output standard.

JVM bertanggungjawab untuk memulakan benang cangkuk . Oleh itu, jika cangkuk yang diberikan telah dimulakan, Java akan membuang pengecualian:

Thread longRunningHook = new Thread(() -> { try { Thread.sleep(300); } catch (InterruptedException ignored) {} }); longRunningHook.start(); assertThatThrownBy(() -> Runtime.getRuntime().addShutdownHook(longRunningHook)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Hook already running"); 

Jelas, kami juga tidak dapat mendaftarkan mata kail berulang kali:

Thread unfortunateHook = new Thread(() -> {}); Runtime.getRuntime().addShutdownHook(unfortunateHook); assertThatThrownBy(() -> Runtime.getRuntime().addShutdownHook(unfortunateHook)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Hook previously registered");

3.2. Mengeluarkan Cangkuk

Java menyediakan kaedah penyingkiran berkembar untuk menghilangkan cangkuk penutupan tertentu setelah mendaftarkannya:

Thread willNotRun = new Thread(() -> System.out.println("Won't run!")); Runtime.getRuntime().addShutdownHook(willNotRun); assertThat(Runtime.getRuntime().removeShutdownHook(willNotRun)).isTrue(); 

Kaedah removeShutdownHook () kembali benar apabila cangkuk penutupan berjaya dikeluarkan.

3.3. Kaveat

JVM menjalankan cangkuk penutupan hanya sekiranya berlaku penamatan biasa. Oleh itu, apabila kekuatan luaran membunuh proses JVM secara tiba-tiba, JVM tidak akan berpeluang untuk melakukan penyambungan penutupan. Selain itu, menghentikan JVM dari kod Java juga akan memberi kesan yang sama:

Thread haltedHook = new Thread(() -> System.out.println("Halted abruptly")); Runtime.getRuntime().addShutdownHook(haltedHook); Runtime.getRuntime().halt(129); 

The terhenti kaedah paksa tamatkan JVM sedang berjalan. Oleh itu, cangkuk penutupan yang didaftarkan tidak akan mendapat peluang untuk dilaksanakan.

4. Kesimpulan

Dalam tutorial ini, kami melihat cara yang berbeza yang dapat ditamatkan oleh aplikasi JVM. Kemudian, kami menggunakan beberapa API runtime untuk mendaftar dan membatalkan pendaftaran cangkuk penutupan.

Seperti biasa, kod sampel boleh didapati di GitHub.