2013-12-11 19 views
16

Mam następujący kod:Java Thread.stop() vs Thread.interrupt()

renderThread = new Thread(new Runnable() { 

    @Override 
    public void run() { 
     for (int i = 0; i < 10000000; i++) { 
      System.out.println("Number: " + i); 
     } 
    } 
}); 

renderThread.start(); 

try { 
    Thread.sleep(100); 
} catch (InterruptedException ex) { 
    ex.printStackTrace(); 
} 

renderThread.interrupt(); //It should stop, but it does not stop. 

renderThread.interrupt() nie przerywa wątek, to nadal działa. Jeśli zmienię renderThread.interrupt() na .stop(), wątek zostanie zatrzymany. Jednak .stop() jest przestarzałe. Następnie, jaki jest właściwy sposób zatrzymania wątku, jeśli stop jest przestarzałe inie działa?

+2

Dlaczego uważasz, że wywołanie 'interrupt' spowoduje _stop_ wątku'? –

+1

możliwy duplikat [Jak właściwie zatrzymać wątek w Javie] (http://stackoverflow.com/questions/10961714/how-to-properly-stop-the-thread-in-java) –

+3

@SotiriosDelimanolis Ponieważ, potocznie, "przerywanie czegoś" i "zatrzymywanie czegoś" są synonimami. Nie mówię, że to właśnie to * robi * (i dokumentacja jest dobrym miejscem do rozpoczęcia rozwijania założenia), ale nazwa jest ładowana. – user2864740

Odpowiedz

18

Po wywołaniu interrupt() wyzwala ona flagę boolowską, która informuje funkcję run, że powinna się zatrzymać. Dlatego zazwyczaj piszę moje funkcje uruchamiania w ten sposób.

void run() 
{ 
    while(!Thread.interrupted()) 
    { 
     //Do something 
    } 
} 

Tylko dlatego, że wywołanie przerwania nie oznacza, że ​​wątek zostanie zatrzymany natychmiast lub w ogóle. To zależy od tego, co jest w funkcji uruchamiania.

+0

Oznacza to, że po wystąpieniu zdarzenia przerwania i dojściu kodu do końca 'run()', wątek automatycznie przestaje istnieć? –

+1

Tak. O ile wiem, wątki powinny się zatrzymywać tylko wtedy, gdy uruchamiane są wyjścia. Przerywanie w działaniu informuje, że powinien wyjść tak szybko, jak to możliwe. Problem z wywołaniem stop() polega na tym, że run() musiał wykonać pewne czyszczenie, jak zamknięcie strumienia, to by się nie stało. – chasep255

+1

Myślę, że to rozwiązanie nie rozwiąże problemu tutaj. Kiedy renderThread wykonuje zadanie, nie ma szansy na sprawdzenie Thread.interrupted(). – Jimmy

6

Aby naprawdę podkreślić, dlaczego nie powinieneś używać Thread.stop()?

Doug Lea niedawno wspomniał, że Thread.stop będzie pierwszy de realizowany metodą Java przyjść Java 8.

Jego odpowiedź na ten komentarz od kogoś:

także synchronizuje się jeszcze jedna rzecz, która obsługuje asynchroniczne przerywanie wątków (np. thread.stop()). Wiem, że stop() jest przestarzały i wszystkie, ale nigdy nie wiadomo.

Czy:

Ale wiem! Od wersji JDK8 wątek.stop naprawdę zniknął. Jest to pierwszy, uznany za przestarzały model, który został faktycznie zaimplementowany. Teraz po prostu rzuca wyjątek UnsupportedOperationException.

http://cs.oswego.edu/pipermail/concurrency-interest/2013-December/012028.html

+5

A jednak Java 8 jest tutaj, podobnie jak Thread.stop ... LOL. –

1

renderThread.interrupt() nie przerwać nić, to nadal uruchomić.

  • Jeśli wątek jest wykonywany i interrupt() wywoływana jest to stan przerwania jest ustawiony.
  • Jeśli ten wątek jest zablokowany w wywołaniu jednej z wait metod klasy Object lub z Thread.join i Thread.sleep metod tej klasy następnie jego status przerwania zostanie skasowana i będzie on posiadać InterruptedException.

Na przykład

Thread t = new Thread() 
     { 
      public void run() 
      { 
       try { 
        for(int i=0; i<10000;i++) 
         System.out.println("Is interrupTed? "+this.isInterrupted()); 

        Thread.sleep(200); 
       } catch (InterruptedException ex) { 
        Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); 
       } 

      } 
     }; 
     t.start(); 
     t.interrupt(); 
    } 

Powyższy kodu, które stosuje się for pętli przechwycić flagę interrput z isInterrupted() funkcji i wydrukowany. Po wywołaniu t.interrupt(), isInterrupted() zwróci true, który zobaczysz w konsoli. Jak tylko dotrze do Thread.sleep(miliTime), zostanie wykryty, że został przechwycony InterruptedException, który został zgłoszony zgodnie z powyższym opisem.

Zatrzymywanie wątek:

można skorzystać z tej kontroli isInterrupted() flagi jeśli interrupt() została wywołana na nim i powrócić z wykonania:

Na przykład:

Thread t = new Thread() 
     { 
      public void run() 
      { 
       long executeTime = System.currentTimeMillis() ; 
       int i = 0;  
       for(; i<10000 && !this.isInterrupted();i++) 
         System.out.println("Is interrupted? "+this.isInterrupted()); 

       System.out.println("Was Interrupted? "+this.isInterrupted() 
            +" after cycle: "+ i); 
       System.out.println("Time it gets Executed: " 
            +(System.currentTimeMillis() - executeTime+" ms")); 

      } 
     }; 
     t.start(); 
     try { 
      Thread.sleep(200); 
     } catch (InterruptedException ex) { 
      ex.printStackTrace(); 
     } 
     t.interrupt(); 

Podczas pracy z powyższym kodem: wysłałem główny wątek do uśpienia dla 200 wewnątrz statycznego główna funkcja pozwalająca uruchomionemu wątkowi t działać przez pewien czas. Wtedy wywoływany
t.interrupt() na nim co powoduje pętlę for się zatrzymać i wydrukować dane wyjściowe w następujący sposób:

Was Interrupted? true after cycle: 1477 
Time it gets Executed: 258 ms 

Co wskazuje, że pętla for ma 1148 iteracji przed t.interrupt(); został wywołany w funkcji main. Aby uzyskać więcej informacji, należy zapoznać się z dokumentacją funkcji Thread.interrupt().

3

wszystko co musisz zrobić, aby przerwać bieżący wątek lub zakończyć proces uruchomiony wątku jest dodać poniższego oświadczenia w ciągu złapać Blokuj

try 
{ 
    Thread.sleep(4000); 
    System.out.println("VAS CONSULTING") 
} 
catch(InterruptedException e) 
{ 
    //Stop printing out VAS CONSULTING 
    return; /*This will terminate the thread*/ 
} 

Także jeśli to metoda, która nie rzuca przerwanego wyjątek ten nie jest stosowany w metodzie run można to zrobić, aby obsłużyć wątek przerwania lub zakończenia wątek

@Override 
public void run() 
{ 

    System.out.println("VAS CONSULTING"); 
    if(Thread.Interrupted()) 
    { 
    doSomethingElse();//process something else within the thread 
    return; //Terminates the current Thread 
    } 

} 

mam nadzieję, że to pomaga czy ktoś inny.