Bagaimana cara menggunakan ayunan di kait penutup?

Apakah ada cara yang mungkin untuk menambahkan ayunan ke dalam kait pematian (yaitu, menampilkan popup saat VM dimatikan)?

Saya menyadari bahwa jika saya mencoba membuat JFrame baru, itu akan memberi saya kesalahan, karena mencoba mendaftarkan hook shutdown, yang gagal karena VM sudah dimatikan. Saya hanya ingin tahu apakah sebenarnya ada jalan keluarnya


person Alex Coleman    schedule 25.08.2012    source sumber
comment
Saya akan mengatakan tidak, & bahkan jika Anda bisa, saya sarankan Anda tidak melakukannya   -  person MadProgrammer    schedule 25.08.2012
comment
@MadProgrammer Saya telah mencari-cari, dan tidak dapat menemukan apa pun, tetapi menurut saya hal itu mungkin terjadi karena banyak aplikasi memberi Anda jendela sembulan, tidak hanya saat ditutup, tetapi seperti jika Anda mematikan komputer (yang pada gilirannya mematikan komputer VM Jawa)   -  person Alex Coleman    schedule 25.08.2012
comment
Saya memiliki program yang baru-baru ini memberikan pengecualian karena pengembang mengakses Komponen Swing dalam hook yang dimatikan (menurut saya di bawah Java 7). Menurut saya, Anda mungkin mengalami masalah saat mencoba mengikuti konsep ini. Sebagian dari masalahnya adalah tidak mengetahui status JVM sebenarnya, atau urutan pemanggilan hook penutupan   -  person MadProgrammer    schedule 25.08.2012
comment
@AlexColeman Tentu saja mungkin untuk menampilkan jendela popup, tetapi tidak melalui kait pematian seperti yang Anda asumsikan. Biasanya hal ini dilakukan pada acara penutupan jendela.   -  person user207421    schedule 26.08.2012
comment
Di Macintosh, Anda dapat memiliki ApplicationListener yang memiliki metode public void handleQuit(ApplicationEvent). Jika Anda ingin mendukung/memiliki mesin Windows, ini tidak akan berfungsi karena ada dalam paket com.apple.   -  person 11684    schedule 27.08.2012


Jawaban (5)


Anda seharusnya tidak melakukan ini. Dari spesifikasi Runtime.addShutdownHook :

Mesin virtual Java dimatikan sebagai respons terhadap dua jenis kejadian:

  • Program keluar secara normal, ketika thread non-daemon terakhir keluar atau ketika metode exit (setara dengan System.exit) dipanggil, atau
  • Mesin virtual dihentikan sebagai respons terhadap interupsi pengguna, seperti mengetik ^C, atau kejadian di seluruh sistem, seperti logoff pengguna atau penutupan sistem.

...

Kait pematian dijalankan pada waktu yang sulit dalam siklus hidup mesin virtual dan oleh karena itu harus diberi kode secara defensif. Secara khusus, mereka harus ditulis agar aman untuk thread dan sedapat mungkin menghindari kebuntuan. Mereka juga tidak boleh bergantung secara membabi buta pada layanan yang mungkin telah mendaftarkan kaitan penutupan mereka sendiri dan karena itu mereka sendiri yang sedang dalam proses penutupan. Upaya untuk menggunakan layanan berbasis thread lainnya seperti thread pengiriman peristiwa AWT, misalnya, dapat menyebabkan kebuntuan.

Kait penutup juga harus menyelesaikan pekerjaannya dengan cepat. Ketika sebuah program memanggil exit, harapannya adalah mesin virtual akan segera dimatikan dan keluar. Ketika mesin virtual dihentikan karena pengguna logoff atau sistem dimatikan, sistem operasi yang mendasarinya hanya dapat memberikan waktu tertentu untuk mematikan dan keluar. Oleh karena itu tidak disarankan untuk mencoba interaksi pengguna apa pun atau melakukan komputasi yang berjalan lama dalam hook shutdown.

...

Dalam keadaan yang jarang terjadi, mesin virtual dapat batalkan, yaitu berhenti berjalan tanpa dimatikan dengan benar. Hal ini terjadi ketika mesin virtual dihentikan secara eksternal, misalnya dengan sinyal SIGKILL di Unix atau panggilan TerminateProcess di Microsoft Windows. Mesin virtual juga dapat dibatalkan jika metode asli menjadi salah, misalnya, merusak struktur data internal atau mencoba mengakses memori yang tidak ada. Jika mesin virtual dibatalkan maka tidak ada jaminan yang dapat dibuat mengenai apakah kait pematian akan dijalankan atau tidak.

Peringatan khusus di sini yang menyarankan Anda tidak melakukan ini:

  1. "Kait penutup juga harus menyelesaikan pekerjaannya dengan cepat."

    Mengandalkan apa pun yang mungkin memerlukan waktu beberapa saat untuk melakukan tugasnya, atau memblokir input pengguna tanpa batas waktu seperti dialog JOptionPane, bukan yang seharusnya Anda lakukan di hook penonaktifan Anda.

  2. "Upaya untuk menggunakan layanan berbasis thread lain seperti thread pengiriman peristiwa AWT, misalnya, dapat menyebabkan kebuntuan"

    Swing berjalan di atas AWT, yang thread pengiriman peristiwa yang mendasarinya mungkin juga sedang dalam proses dimatikan. Mencoba menggunakan Swing atau AWT saat mematikan tidak hanya dapat menyebabkan kunci mati tetapi juga mungkin tidak berfungsi sama sekali.

  3. "Jika mesin virtual dibatalkan maka tidak ada jaminan yang dapat dibuat mengenai apakah hook pematian akan dijalankan atau tidak"

    Tidak ada jaminan bahwa pengguna Anda mungkin bisa menerima pesan Anda, karena kait penonaktifan hanya dijamin berjalan ketika keluar secara normal atau dihentikan -- tidak ketika dihentikan atau dibatalkan.

person obataku    schedule 25.08.2012
comment
Ini yang saya pahami sebelumnya, berharap akan ada jalan, tapi saya rasa tidak - person Alex Coleman; 25.08.2012

Kait pematian seharusnya dijalankan secepat mungkin. Itu tidak termasuk menunggu pengguna mengonfirmasi dialog. Bagaimanapun Anda tidak memiliki jaminan bahwa thread acara Swing masih berjalan.

Anda tidak bisa melakukan ini.

person user207421    schedule 25.08.2012
comment
+1 bagus Anda tidak memiliki jaminan bahwa rangkaian acara Swing masih berjalan - person David Kroukamp; 25.08.2012

Jika ada, itu tidak akan membantu Anda.

Kait pematian dipanggil secara asinkron sebagai bagian dari pematian JVM, jadi dialog "konfirmasi" tidak akan benar-benar mengonfirmasi apa pun karena Anda tidak dapat menghentikan atau membalikkan proses pematian. Menunggu pengguna untuk membuat keputusan bukanlah tindakan yang dimaksudkan untuk mematikan hook. Kait mematikan dalam program interaktif tidak masuk akal. Kasus penggunaan sebenarnya untuk kait pematian adalah:

untuk melepaskan sumber daya dan pembersihan lainnya saat JVM dimatikan

Penting juga untuk dicatat bahwa shut down hook tidak selalu dijalankan, untuk lebih lanjut lihat jawaban saya di sini: Cara mematikan aplikasi java dengan benar dari C# one

person David Kroukamp    schedule 25.08.2012
comment
Meskipun ditangani secara asinkron, thread tetap bukan daemon sehingga mungkin masih berfungsi... namun Anda tidak boleh pernah melakukannya. - person obataku; 25.08.2012
comment
@veer benar tapi saya kira masalah terbesar yang akan dihadapi OP adalah tidak semua penghentian aplikasi akan memanggil kait pematian - person David Kroukamp; 25.08.2012

  1. Swing GUI harus dilakukan di Event Dispatch Thread, lalu

  2. Cara sederhana, namun memerlukan tindakan pengguna akhir (tutup JDialog)

person mKorbel    schedule 25.08.2012
comment
Saya khawatir saya tidak melihat relevansi jawaban Anda dengan pertanyaan awal. - person Duncan Jones; 25.08.2012
comment
@DuncanJones Dia menjawabnya. Jawabannya adalah tentang mematikan kait + tautan ke solusi yang mungkin... - person Alex Coleman; 25.08.2012
comment
@mKorbel Saya tidak mengerti cara kerja opsi pertama; Saya tidak meminta kait pematian, ini terjadi secara acak, saya hanya ingin menanganinya dengan jendela sembulan. Untuk yang kedua, saya melihat beberapa potensi di dalamnya, namun apakah Runtime#exec akan berfungsi ketika JVM/komputer dimatikan? - person Alex Coleman; 25.08.2012
comment
@Alex Coleman Runtime#exec adalah salah satu dari tujuh opsi, jika ada sesuatu yang Anda tidak mengerti, cari pertanyaan tentang JVM, Swing dan mengapa Shutdown Hook tidak berfungsi untuk Swing GUI dengan tugas latar belakang - person mKorbel; 25.08.2012

Saya tidak yakin dengan pertanyaan Anda, tapi menurut saya tidak mungkin menjalankan atau menampilkan jendela popup saat JVM dimatikan. Ini seperti kamu mencoba berlari sambil bersiap untuk tidur? Hanya menebak. :)

person user1577161    schedule 25.08.2012