IT박스

catch InterruptException 블록에서 Thread.currentThread.interrupt ()를 호출하는 이유는 무엇입니까?

itboxs 2020. 6. 22. 08:06
반응형

catch InterruptException 블록에서 Thread.currentThread.interrupt ()를 호출하는 이유는 무엇입니까?


Thread.currentThread.interrupt()catch 블록에서 메소드 호출하는 이유는 무엇 입니까?


이것은 상태유지 하기 위해 수행됩니다 .

당신이 InterruptException그것을 잡아 삼킬 때, 당신은 본질적으로 더 높은 수준의 메소드 / 스레드 그룹이 인터럽트를 알지 못하게합니다. 문제가 발생할 수 있습니다.

을 호출 Thread.currentThread().interrupt()하면 스레드의 인터럽트 플래그를 설정하므로 높은 수준의 인터럽트 핸들러가이를 감지하여 적절히 처리 할 수 ​​있습니다.

실제로 Java Concurrency는 이에 대한 자세한 내용은 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

오랜 시간 동안 대기하는 스레드를 어떻게 중지합니까 (예 : 입력)?

For this technique to work, it's critical that any method that catches an interrupt exception and is not prepared to deal with it immediately reasserts the exception. We say reasserts rather than rethrows, because it is not always possible to rethrow the exception. If the method that catches the InterruptedException is not declared to throw this (checked) exception, then it should "reinterrupt itself" with the following incantation:

Thread.currentThread().interrupt();

This ensures that the Thread will reraise the InterruptedException as soon as it is able.


I would consider it a bad practice or at least a bit risky. Usually higher level methods do not perform blocking operations and they will never see InterruptedException there. If you mask it in every place you perform interruptible operation, you will never get it.

The only rationale for Thread.currentThread.interrupt() and not raising any other exception or signaling interrupt request in any other way (e.g. setting interrupted local variable variable in a thread's main loop) is the situation where you really can't do anything with the exception, like in the finally blocks.

See Péter Török's answer, if you want to better understand implications of the Thread.currentThread.interrupt() call.

참고URL : https://stackoverflow.com/questions/4906799/why-invoke-thread-currentthread-interrupt-in-a-catch-interruptexception-block

반응형