2012-10-31 14 views
8

Próbuję uzyskać hak zamknięcia do pracy na moim serwerze ubuntu, jednak wydaje się, że problem z więcej niż jednego wątku. Używając podstawowego ShutdownHook, poniższy kod działa, gdy zabijam proces przy użyciu kill <PID>, co oznacza, że ​​aktywowane jest działanie shutdown.Zamknięcie java java z więcej niż jednego wątku

public static void main(String[] args) { 
    ShutdownHook shutDown = new ShutdownHook(); 
    shutDown.attachShutDownHook(); 

    while(true){} 
} 

jednak ten sam kod z dodatkowym gwintem nie

public static void main(String[] args) { 
    ShutdownHook shutDown = new ShutdownHook(); 
    shutDown.attachShutDownHook(); 

    (new Thread() { 
     public void run() { 
      while (true) {} 
     } 
    }).start(); 

    while(true){} 
} 

jakieś pomysły?

class ShutdownHook { 

    ShutdownHook() { 
    } 

    public void attachShutDownHook() { 

      Runtime.getRuntime().addShutdownHook(new Thread() { 
        @Override 
        public void run() { 
          System.out.println("Shut down hook activating"); 
        } 
      }); 
      System.out.println("Shut Down Hook Attached."); 

    } 
} 
+0

Jakie zachowanie ma drugi wątek? Czy aplikacja zatrzymuje się, nie wywołując zachowania zamykającego? Mówisz też "zabij proces". Co przez to rozumiesz? Jak to kończysz? – Gray

+0

Drugi wątek jest tylko przykładem wątku na żywo. W moim rzeczywistym przykładzie nasłuchuje połączeń na porcie i pozostaje żywy przez cały czas trwania programu. Kończę proces za pomocą 'kill '. Drugi z powyższych programów nie działa tak, jak jest, więc jest coś czego mi brakuje w odniesieniu do więcej niż jednego wątku. – Reese

+0

Spróbuj uruchomić 'jstack ' po uruchomieniu 'kill', aby zobaczyć, które wątki wciąż działają. – SimonC

Odpowiedz

0

java.lang.Runtime.addShutdownHook(Thread) rejestruje nowy hak zamykania virtual-machine:

Maszyna wirtualna Java zamyka w dół w reakcji na dwóch rodzajach wydarzeń:

  • Program zakończy się normalnie, gdy ostatni wątek nie będący demonem zostanie zamknięty lub gdy zostanie wywołana metoda wyjścia (równoważnie metoda System.exit) lub

  • Maszyna wirtualna jest przerywana w odpowiedzi na przerwanie użytkownika, takie jak pisanie^C lub zdarzenie systemowe obejmujące użytkownika lub system.

Twoje uruchamia kod w nieskończoność więc hak zamykania nigdy nie zostanie wywołana.

[Po edytuj]

Które kill używacie?

zabitych -9 jest NON trappable

zabić -2 może być stosowany do naśladowania Ctrl-C (SIGINT)

+0

Używam 'kill ' bez żadnych dodatkowych argumentów. Powinien być to pułapka, i faktycznie działa w scenariuszu z jedną nicią. – Reese

3

JVM nie zakończy gdy wciąż nie demon nitki prowadzące. Spróbuj zadzwonić pod numer setDaemon(true) w nowym wątku.

+0

Nie wydaje się, żeby to było możliwe. – Reese

1

Aby wziąć przykład z własnego projektu;

Moja podstawowa klasa spawnuje całą masę wątków roboczych, pracownicy przeprowadzają transakcje, które muszą zostać zakończone.

W klasie podstawowej mam;

Runtime.getRuntime().addShutdownHook(new ShutdownCleanup()); 

Który wygląda podobnie; Pojawia się komunikat log

public final class ShutdownCleanup extends Thread() { 
    public void run() { 
     log("waiting for worker threads to finish..."); 
     while(WorkerThread.transactionInProgress()) { 
      Thread.sleep(1000); 
     } 
     //close various sockets and resources 
    } 
} 

Moment uderzę Ctrl+C w terminalu. Tak więc hak zamykający aktywuje się natychmiast, to nie jest coś, co uruchamia się, gdy program jest gotowy na śmierć, a raczej działa, gdy tylko otrzyma żądanie zamknięcia lub zabicia.

Z tego powodu wierzę w to, co inni powiedzieli o hakach wyłączania, które nigdy nie zostały wywołane, podczas gdy wciąż żywa jest wątek, jest fałszywe.Jaki byłby sens haka wyłączającego, który aktywował się tylko wtedy, gdy wszystko zginęło?

Możliwe, że używasz twardego zabijania, na przykład -9. Czy próbowałeś normalnego wyłączenia przy pomocy Ctrl+C lub SIGINT?

+0

Tak, próbowałem 'kill ' bez argumentów, oraz 'CTRL + C'. Oba działają w pierwszym, pojedynczym przykładzie z gwintem i nie działają tak szybko, jak mam więcej niż jeden wątek. Być może brakuje mi jakiegoś wątku? – Reese

+0

Czy próbowałeś już użyć powyższej metody 'Runtime'? Nie mam pojęcia, co by to zmieniło, ale może podłączasz hak do jednego wątku zamiast do JVM ... jeśli to możliwe. – lynks

+0

Używam Runtime. Zaktualizowałem moje oryginalne pytanie, aby pokazać sam ShutdownHook – Reese

Powiązane problemy