80

Kiedy Java's Thread.sleep rzuca wyjątek InterruptedException? Czy można go zignorować? Nie robię wielowątkowości. Chcę tylko poczekać kilka sekund, zanim spróbuję wykonać jakąś operację.Kiedy Java's Thread.sleep rzuca wyjątek InterruptedException?

+2

http://stackoverflow.com/questions/1024651/do-i-have-to- worry- about-interruptedexceptions-if-i-dont-interrupt-anything-myse –

+1

Zależy od tego, w jakim sensie masz na myśli "ignoruj" . 'InterruptedException' jest złapanym wyjątkiem, więc nie można go skompilować, dopóki nie obsłużysz lub nie zadeklarujesz tego typu wyjątku w żadnej metodzie, która łączy lub śpi w" wątku ", lub wywołuje' wait() 'na' Object'. – 8bitjunkie

+1

Ten artykuł może pomóc w zrozumieniu tego mechanizmu: [Co robisz z przerwanym wyjątkiem?] (Http://www.yegor256.com/2015/10/20/interrupted-exception.html) – yegor256

Odpowiedz

24

Powinieneś zasadniczo NIE ignorować wyjątku. Spójrz na poniższym artykule:

Nie połykać przerwań

Czasami rzuca InterruptedException jest nie wchodzi w grę, na przykład gdy zadanie określone przez Runnable wzywa metoda przerywana. W takim przypadku nie można ponownie wykryć wyjątku InterruptedException, ale także nie chcesz nic robić. Gdy metoda blokowania wykryje przerwanie i rzuci wyjątek InterruptedException, , usunie przerwany status. Jeśli wykryjesz InterruptedException , ale nie możesz go ponownie rzucić, powinieneś zachować dowód na to, że nastąpiło przerwanie , aby kod znajdujący się wyżej na stosie wywołań mógł uzyskać informację o przerwie i odpowiedzieć na nią, jeśli tego chce. To zadanie jest wykonywane przez wywołanie metody interrupt() w celu "ponownego przesłania" bieżącego wątku , jak pokazano na listingu 3. Przynajmniej, gdy przechwycisz InterruptedException i nie wyrzucisz go, ponownie prześlij bieżący wątek przed powrotem.

public class TaskRunner implements Runnable { 
    private BlockingQueue<Task> queue; 

    public TaskRunner(BlockingQueue<Task> queue) { 
     this.queue = queue; 
    } 

    public void run() { 
     try { 
      while (true) { 
       Task task = queue.take(10, TimeUnit.SECONDS); 
       task.execute(); 
      } 
     } 
     catch (InterruptedException e) { 
      // Restore the interrupted status 
      Thread.currentThread().interrupt(); 
     } 
    } 
} 

Zobacz cały papier tutaj:

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs-

+0

strona nie została znaleziona. Czy mógłbyś zaktualizować swój post? – Laurence

+1

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs- –

4

Solidny i łatwy sposób obsługiwać go w jednym kodem gwintowany będzie b e, aby go przechwycić i powrócić do wyjątku RuntimeException, aby uniknąć deklarowania go dla każdej metody.

9

Biuletyn Java Specialists (który mogę bez zastrzeżeń polecać) miał interesting article on this i jak obsługiwać InterruptedException. Warto czytać i trawić.

-4

Zazwyczaj wywoływany jest w przypadku przerwania uśpienia.

+11

To źle, ponieważ to nie sam sen jest przerywany, ale wątek go uruchamia. Przerwano jest stanem wątku. Prowadzi to do wyjścia z metody uśpienia. – ubuntudroid

23

Jeśli zostanie zgłoszony wyjątek InterruptedException, oznacza to, że coś chce przerwać (zwykle zakończyć) ten wątek. Jest to wywoływane przez wywołanie metody interrupt() dla wątków. Metoda wyczekiwania wykrywa to i generuje wyjątek InterruptedException, aby kod catch mógł natychmiast obsłużyć żądanie usunięcia i nie musi czekać, aż upłynie określony czas.

Jeśli używasz go w aplikacji jednowątkowej (a także w niektórych aplikacjach wielowątkowych), ten wyjątek nigdy nie zostanie wyzwolony. Ignorując go, mając klauzulę pustego połowu, nie polecam. Rzucanie wyjątku InterruptedException powoduje skasowanie przerwanego wątku wątku, więc jeśli nie zostanie poprawnie obsłużone, informacje zostaną utracone. Dlatego też proponuję uruchomić:

} catch (InterruptedException e) { 
    Thread.currentThread().interrupt(); 
    // code for stopping current task so thread stops 
} 

Który zestawuje ponownie. Następnie zakończ wykonywanie.Byłoby to prawidłowe zachowanie, nawet trudne nigdy nie używane.

Co może być lepiej jest dodać:

} catch (InterruptedException e) { 
    assert false; 
} 

oświadczenie do bloku catch. To w zasadzie oznacza, że ​​nigdy nie może się zdarzyć. Jeśli więc kod zostanie ponownie użyty w środowisku, w którym może się zdarzyć, będzie narzekał na to.

+4

Asercje w Javie są [domyślnie wyłączone] (http://stackoverflow.com/a/2758645/1143274). Więc lepiej jest rzucić 'RuntimeException'. –

0

Metody takie jak sleep() i wait() klasy Thread mogą rzucić InterruptedException. Stanie się tak, jeśli jakiś inny thread chciał przerwać thread, który czeka lub śpi.