Java Thread Sleep и прерванное исключение

  1. почему поток сна нуждается в улове try, чтобы поймать прерванное исключение?
  2. почему сон даже выдает прерванную ошибку исключения? Это два вопроса, о которых я действительно хочу узнать в Java-программировании Я искал через google, и я до сих пор не нашел четкого объяснения тому, почему эти две вещи происходят.

6 ответов


1.- Потому что поток не может завершить свое нормальное выполнение, Если вы его прерываете, и вам нужно поймать это, чтобы быть готовым что-то сделать. 2.- Поскольку ожидание потока отличается от прерванного потока, ожидание потока может быть возобновлено, но прерванный поток уже завершает выполнение.


An InterruptedException бросается, когда поток заблокирован / ждет и прерывается другим потоком (с помощью Thread.interrupt). Думайте об этом как о просьбе о немедленном прекращении, которые не страдают недостатками Thread.stop().

таким образом, даже если вы проинструктируете поток спать в течение нескольких лет, вы можете прервать этот поток.

рекомендуемая практика прерывает все, что вы обрабатываете, когда InterruptedException бросается.


когда вы просите поток спать, ожидаемое поведение для этого потока-спать в течение этого времени. Поэтому, если сон прерывается, он будет вызывать InterruptedException, чтобы указать, что он не смог выполнить задачу. И вы, возможно, захотите позаботиться о том, что следует сделать, если он будет прерван.


есть чистый пример того, как прерванное исключение может быть брошено здесь:http://www.javamex.com/tutorials/threads/thread_interruption.shtml

и дискутировать о sleep() и yield() здесь:http://www.coderanch.com/t/508657/threads/java/Sleep-Yield-state


потому что sleep() потенциально может блокировать навсегда / долгое время, поэтому вам нужен способ отменить это поведение. Поскольку это не" нормальное " завершение, когда вы прерываете действие, вам может потребоваться выполнить определенное компенсирующее или корректирующее действие, например, отправить предупреждение о том, что вы никогда не получали уведомления, очистить ресурсы и т. д.
Есть довольно хороший разработчик статья на эту тему.


сон и прерывания не связаны семантически. Просто дизайнеры Java думали, что когда вы хотите, чтобы ваш поток спал, это хорошая возможность напомнить вам о прерываниях. Это как герцог слова " похоже, вы пытаетесь спать, вы также хотели бы сделать свой поток хорошим гражданином, убедившись, что он правильно реагирует на прерывание событий, когда необходимость в способе заставить его резко прерваться на более поздней стадии вашего проекта возникает?"

поэтому часто можно увидеть такой код:

try {
    Thread.sleep(1000);
} catch (InterruptedException ie) {
    //Don't worry about it.
}

иногда люди говорят, что это считается плохой практикой. Но если вы не планируете использовать средство прерывания в своей программе, то эти исключения никогда не будут выброшены, поэтому вы должны спросить себя, имеет ли смысл делать дополнительную работу, чтобы позаботиться об этих исключениях, в случае, если вы решите добавить функцию прерывания в свою программу через некоторое время. Это один из тех то, что дизайнеры Java настаивали на том, что каждый поток должен делать - что вы можете interrupt() это, и это будет быстро и чисто прервать то, что он делает. Я думаю, что во многих случаях это не нужно, но люди будут смотреть на ваш код, видеть это и все равно говорить: "эээ, плохая практика!"

официальный учебник Java объясняет прерывания. В принципе, если у вас есть один поток t делает некоторую обработку, а затем пользователь хочет отменить ее, из другого потока вы бы позвонили t.interrupt(). В коде, который работает в потоке t, когда он sleep()или wait()s, etc. Ан InterruptedException будет брошен. Если он не делает ничего из этого, то он может (должен) также узнать, был ли он прерван с помощью Thread.interrupted() время от времени. Во всех этих способах узнать о прерываниях он должен отказаться от того, что он делает, и очистить как можно скорее. (То есть: если это так, то это поведение может быть полезно вам или кому - то-это идея прерывание.)

Итак, Java делает это проверенным исключением sleep(..) способ, чтобы заставить вас думать об использовании этого объекта. Другая часть причины заключается в том, что если sleep(..) прерывается, тогда он проснется рано, и это исключительное событие. (Но помните, что это "если".)

важно то, что прерывания не происходят просто так без причины. Они происходят, если вы пишете код, чтобы они произошли, или если кто-то другой делает, кто запускает ваши потоки и имеет необходимость отменить свои действия. Так вот кто вызывает Thread.sleep(..) бросить InterruptedException. Вы делаете. А если нет, то все равно нужно поймать.


правка. кстати, было бы лучше сделать это так:

try {
    Thread.sleep(1000);
} catch (InterruptedException ie) {
    throw new UnsupportedOperationException("Interrupts not supported.", ie);
}

Итак, если вы или кто-то другой когда-либо попытается прервать этот поток по ошибке позже, то, когда они пойдут, чтобы проверить его, им напомнят, что эта функция не реализуется. (UnsupportedOperationException является наследником RuntimeException, так что это не отмечено.)