Зачем вызывать поток.currentThread.interrupt () в блоке catch InterruptException?



зачем вызывать метод Thread.currentThread.прервать() в блоке catch?

588   4  

4 ответов:

это делается для сохранить состояние.

когда вы ловите InterruptException и проглотить его, вы по существу предотвратить любые методы более высокого уровня / группы потоков от заметив прерывание. Что может вызвать проблемы.

по телефону Thread.currentThread().interrupt(), вы устанавливаете флаг прерывания потока, поэтому обработчики прерываний более высокого уровня заметят его и смогут обрабатывать его соответствующим образом.

параллелизм Java на практике обсуждает это более подробно глава 7.1.3: реагирование на прерывание. Его правило таково:

только код, реализующий политику прерывания потока, может проглотить запрос прерывания. Универсальный код задачи и библиотеки никогда не должен проглатывать запросы на прерывание.

Я думаю, что этот пример кода делает вещи немного понятно. Класс, который выполняет эту работу:

   public class InterruptedSleepingThread extends Thread {

        @Override
        public void run() {
            doAPseudoHeavyWeightJob();
        }

        private void doAPseudoHeavyWeightJob() {
            for (int i=0;i<Integer.MAX_VALUE;i++) {
                //You are kidding me
                System.out.println(i + " " + i*2);
                //Let me sleep <evil grin>
                if(Thread.currentThread().isInterrupted()) {
                    System.out.println("Thread interrupted\n Exiting...");
                    break;
                }else {
                    sleepBabySleep();
                }
            }
        }

        /**
         *
         */
        protected void sleepBabySleep() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                //e.printStackTrace();
                Thread.currentThread().interrupt();
            }
        }
    }

Основной Класс :

   public class InterruptedSleepingThreadMain {

        /**
         * @param args
         * @throws InterruptedException
         */
        public static void main(String[] args) throws InterruptedException {
            InterruptedSleepingThread thread = new InterruptedSleepingThread();
            thread.start();
            //Giving 10 seconds to finish the job.
            Thread.sleep(10000);
            //Let me interrupt
            thread.interrupt();
        }

    }

попробуйте вызвать прерывание, не устанавливая статус обратно.

Примечание:

http://download.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

как остановить поток, который ждет в течение длительного времени (например, для ввода)?

для работы этого метода важно, чтобы любой метод, который ловит исключение прерывания и не готов к его обработке, немедленно подтвердил исключение. Мы говорим утверждает, а не переосмысливает, потому что это не всегда возможно, чтобы повторно сгенерировать исключение. если метод, который ловит InterruptedException, не объявлен, чтобы бросить это (проверенное) исключение, то он должен "переинтерпретировать себя" со следующим заклинанием:

Thread.currentThread().interrupt();

это гарантирует, что поток будет reraise InterruptedException, как только это возможно.

Я бы счел это плохой практикой или, по крайней мере, немного рискованной. Обычно методы более высокого уровня не выполняют операции блокировки, и они никогда не увидят InterruptedException там. Если вы замаскируете его в каждом месте, где вы выполняете прерываемую операцию, вы никогда не получите его.

единственное обоснование Thread.currentThread.interrupt() и не вызывая никакого другого исключения или запроса прерывания сигнализации любым другим способом (например, установка interrupted локальная переменная переменная в основном цикле потока) - это ситуация, когда вы действительно ничего не могу сделать с исключением, как в finally блоки.

смотрите ответ Петера Терека, если вы хотите лучше понять последствия Thread.currentThread.interrupt() звонок.

Comments

    Ничего не найдено.