2012-08-25 10 views
6

Czy jest jakikolwiek sposób na dodanie huśtawki do haka zamykającego (czyli wyświetlenie okna popup przy wyłączaniu maszyny wirtualnej)?Jak używać huśtawki w haku wyłączającym?

Zdaję sobie sprawę, że jeśli spróbuję stworzyć nową ramkę JFrame, spowoduje to błąd, ponieważ próbuje zarejestrować hak zamykający, co nie powiedzie się, ponieważ maszyna wirtualna jest już zamykana. Zastanawiam się, czy istnieje jakikolwiek sposób w rzeczywistości wokół tej

+3

bym nie powiedzieć, i nawet jeśli Coud, polecam, że dont – MadProgrammer

+0

@MadProgrammer Mam rozejrzał się i nie mógł znaleźć nic, ale myślałem, powinno być możliwe w wielu zastosowaniach daje ci okienko wyskakujące, nie tylko po zamknięciu, ale jak w przypadku wyłączenia komputera (który z kolei wyłącza maszynę Java VM) –

+0

Mam program, który ostatnio rzucił wyjątek, ponieważ programista uzyskiwał dostęp do komponentu Swing w haku zamykającym (Myślę, że pod Javą 7). Powiedziałbym, że możesz mieć problem, który próbuje podążać za tą koncepcją. Częścią problemu jest nie wiedzieć, w jakim stanie jest JVM, lub kolejność, w której haki zamykające są nazywane – MadProgrammer

Odpowiedz

13

Naprawdę nie powinieneś tego robić.Od the Runtime.addShutdownHook specification:

Java maszyna wirtualna wyłącza w odpowiedzi na dwa rodzaje zdarzeń:

  • Program wychodzi normalnie, gdy ostatnie non-demon wychodzi gwint lub gdy exit (równoważnie, System.exit) metoda jest wywoływana lub
  • Maszyna wirtualna jest zakończona w odpowiedzi na przerwanie użytkownika, na przykład wpisanie ^C lub zdarzenie o zasięgu systemowym, takie jak wylogowanie użytkownika lub zamknięcie systemu.

...

Shutdown haki prowadzony przy delikatnym momencie cyklu życia maszyny wirtualnej, a zatem powinny być kodowane defensywnych. Powinny one w szczególności zostać napisane w sposób bezpieczny dla wątków i w miarę możliwości unikać zakleszczeń. Nie powinni również polegać na ślepo na usługach, które mogły rejestrować własne haki zamykające, a zatem same w sobie mogą być zamykane. Próby użycia innych usług opartych na wątkach, takich jak na przykład wątek AWT, mogą spowodować zakleszczenia.

Haki zamykające również powinny szybko zakończyć pracę. Gdy program wywołuje exit, oczekuje się, że maszyna wirtualna zostanie natychmiast zamknięta i zakończona. Gdy maszyna wirtualna zostanie zakończona z powodu wylogowania użytkownika lub wyłączenia systemu, podstawowy system operacyjny może zezwolić na określony czas tylko na zamknięcie i zakończenie działania. Dlatego nie jest wskazane podejmowanie jakichkolwiek interakcji z użytkownikiem lub wykonywanie długich obliczeń w haku wyłączającym.

...

W rzadkich przypadkach maszyna wirtualna może przerwać, czyli przestać działać bez wyłączania czysto. Dzieje się tak, gdy maszyna wirtualna jest zamykana na zewnątrz, na przykład za pomocą sygnału SIGKILL w systemie Unix lub połączenia TerminateProcess w systemie Microsoft Windows. Maszyna wirtualna może również przerwać pracę, jeśli natywna metoda okaże się nieskuteczna, na przykład, powodując uszkodzenie wewnętrznych struktur danych lub próbując uzyskać dostęp do nieistniejącej pamięci. Jeśli maszyna wirtualna przerwie się, wówczas nie można zagwarantować, czy zostaną uruchomione jakiekolwiek haki zamykające.

Szczególne ostrzeżenia tutaj, że proponuję nie to zrobić:

  1. "haki zamykania powinna również zakończyć swoją pracę szybko."

    Powołując się na niczego że może potrwać to zrobić swoją pracę, lub blokowanie na czas nieokreślony na łatwość wejścia jak JOptionPane dialogów, jest nie co należy robić w swoim hakiem zamykania.

  2. „Próby do korzystania z innych usług wątków opartych takich jak AWT zdarzenia wysyłki wątku, na przykład, może doprowadzić do zakleszczenia”

    Swing biegnie na górze AWT, którego bazowy zdarzenia wysyłka wątek może być również w trakcie zamykania.Próba użycia Swinga lub AWT podczas wyłączania może prowadzić nie tylko do martwych blokad, ale i tak może w ogóle nie działać.

  3. „Jeśli maszyna wirtualna przerywa wtedy nie ma gwarancji mogą być wykonane o tym, czy jakieś haki zamykania zostanie uruchomiony”

    Nie ma żadnych gwarancji Twój użytkownik może jeszcze ewentualnie otrzymać wiadomość, gdyż haki zamykania mogą być uruchamiane tylko wtedy, gdy normalnie zakończą działanie lub zostaną zakończone - , a nie po ich zatrzymaniu lub przerwaniu.

+0

+1 fajne więcej informacji na OP –

+1

+1 mnóstwo miłych informacji i uwielbiałem podsumowanie – MadProgrammer

+0

To, co wcześniej zrozumiałem, miało nadzieję, że będzie sposób, ale przypuszczam, że nie –

2
  1. Swing GUI muszą być wykonane na Event Dispatch Thread, następnie

  2. Simple way, ale wymaga działania użytkownika końcowego (blisko JDialog)

+0

Obawiam się, że nie widzę, jakie znaczenie ma twoja odpowiedź na oryginalne pytanie. –

+0

@DuncanJones Odpowiada. Jego odpowiedź brzmi: hak zamknięcia + linki do możliwego rozwiązania ... –

+0

@mKorbel Nie widzę, jak działałaby pierwsza opcja; Nie dzwonię do haka zamykającego, dzieje się to jako przypadkowe zdarzenie, chcę tylko obsłużyć to za pomocą wyskakującego okienka. Po drugie, widzę w tym pewien potencjał, jednak czy Runtime # exec będzie działać, gdy JVM/komputer się wyłączy? –

2

Jeśli nie jest, to nie pomoże.

Haczyki zamknięcia są wywoływane asynchronicznie w ramach zamykania JVM, więc okno dialogowe "Potwierdź" nie potwierdzi niczego, ponieważ nie można zatrzymać lub cofnąć procesu zamykania. Oczekiwanie na podjęcie decyzji przez użytkownika nie jest rodzajem działania, do którego przeznaczony jest hak zamykający. Haczyk zamknięcia w interaktywnym programie nie ma sensu. Sprawa wykorzystanie rzeczywistego dla haków Shutdown jest:

za udostępnianie zasobów i innych sprzątanie gdy JVM shutsdown

Ważne jest również, aby zwrócić uwagę na wyłączenie hak przyzwyczajenie zawsze być uruchamiane na więcej zobacz moja odpowiedź tutaj: How to shutdown java application correctly from C# one

+0

Pomimo tego, że jest obsługiwany asynchronicznie, wątek nadal nie jest demonem i dlatego może nadal działać ... nie, że powinieneś __ever__ to zrobić. – oldrinb

+0

@veer true, ale myślę, że największym problemem, z którym boryka się OP, jest to, że nie wszystkie zakończenia aplikacji wywołają hak zamykający –

-1

Nie jestem pewien co do twojego pytania, ale myślę, że to niemożliwe by uruchomić albo wyświetlić okno wyskakujące kiedy JVM zamyka się. To jak próbujesz biec, przygotowując się do snu? Tylko zgaduję. :)

4

Haki zamykające powinny działać tak szybko, jak to możliwe. Nie obejmuje to czekania, aż użytkownik potwierdzi okno dialogowe. W żadnym wypadku nie masz gwarancji, że wątek zdarzenia Swing nadal działa.

Nie możesz tego zrobić.

+0

+1 "nie masz gwarancji, że wątek zdarzenia Swing nadal działa" –

Powiązane problemy