2013-04-05 15 views
5

ja szukaliśmy sposobów, aby zabić wątek i wydaje się, że jest to najbardziej popularne podejściemetoda alternatywna zabić wątek

public class UsingFlagToShutdownThread extends Thread { 
    private boolean running = true; 
    public void run() { 
    while (running) { 
     System.out.print("."); 
     System.out.flush(); 
     try { 
     Thread.sleep(1000); 
     } catch (InterruptedException ex) {} 
    } 
    System.out.println("Shutting down thread"); 
    } 
    public void shutdown() { 
    running = false; 
    } 
    public static void main(String[] args) 
     throws InterruptedException { 
    UsingFlagToShutdownThread t = new UsingFlagToShutdownThread(); 
    t.start(); 
    Thread.sleep(5000); 
    t.shutdown(); 
    } 
} 

Jednakże, jeśli w pętli while my tarło kolejny kolejny przedmiot, który zostanie zapełniony dane (powiedzmy, że GUI działa i aktualizuje), a następnie w jaki sposób oddzwonimy - szczególnie biorąc pod uwagę, że ta metoda mogła zostać wywołana kilka razy, więc mamy wiele wątków z czasem (działa), a zmiana flagi na jedną spowoduje zmianę dla wszystkich?

dzięki

+4

** Nie rozwiązanie, ale najlepsze praktyki: ** Deklarują swoją flagę 'running' jako' volatile'. –

+0

Najlepszym podejściem do zabijania nici jest nie próbowanie. Jeśli istnieje sposób, w jaki można zaprojektować aplikację, aby wątki nie musiały być zabijane, dopóki system operacyjny nie zabije ich podczas kończenia procesu, należy to zrobić dokładnie. –

+0

, ale jeśli metoda run ma nieskończoną pętlę, nawet jeśli zamkniesz gui, do którego wątek przesyła dane, to nadal nie umrze :( – Biscuit128

Odpowiedz

2

Jedno podejście do tych problemów jest mieć klasę monitora, który obsługuje wszystkie wątki. Może uruchomić wszystkie niezbędne wątki (możliwe, że w różnych momentach/gdy jest to konieczne) i gdy chcesz się wyłączyć, możesz wywołać metodę zamknięcia, która przerywa wszystkie (lub niektóre) wątki.

Również faktycznie wywołanie metody Thread s interrupt() jest ogólnie ładniejsza podejście jak to będzie wydostać się z blokowania działania, które rzucają InterruptedException (czekać/uśpienia na przykład). Wtedy będzie ustawić flagę, która już istnieje w wątkach (co można sprawdzić za pomocą isInterrupted() lub sprawdzone i wyczyszczone z interrupted() Na przykład poniższy kod może zastąpić aktualny kod.

public class UsingFlagToShutdownThread extends Thread { 
    public void run() { 
    while (!isInterrupted()) { 
     System.out.print("."); 
     System.out.flush(); 
     try { 
     Thread.sleep(1000); 
     } catch (InterruptedException ex) { interrupt(); } 
    } 
    System.out.println("Shutting down thread"); 
    } 
    public static void main(String[] args) 
     throws InterruptedException { 
    UsingFlagToShutdownThread t = new UsingFlagToShutdownThread(); 
    t.start(); 
    Thread.sleep(5000); 
    t.interrupt(); 
    } 
} 
+2

Czy masz na myśli 'while (! isInterrupted()) '? – z5h

+0

Oczywiście, dziękuję! – ddmps

+1

Jest to zalecany sposób w książce" Współbieżność Java w praktyce ", która jest współautorem projektów współbieżnych JDK (Tim Peierls Joshua Bloch Joseph Bowbeer David Holmes i Doug Lea). .stop' jest absolutnie depreca przetrząsać. –

0

I dodaje klasę utlility który w zasadzie miał statyczną mapę i metody.Alternatywna mapa i metody:

mapa była typu Long id, Thread thread. Dodałem dwie metody jeden do dodania do mapy i jeden do zatrzymania wątku za pomocą przerwania.Ta metoda przyjęła id jako parametr.

Zmieniłem również logikę pętli z while prawda, też za chwilę! isInterrupted. Jest to podejście ok czy jest to zły styl programowania/Convention

dzięki