Programing

Thread.current를 호출하는 이유캐치 인터럽트Exception 블록의 스레드.인터럽트()?

c10106 2022. 5. 16. 20:13
반응형

Thread.current를 호출하는 이유캐치 인터럽트Exception 블록의 스레드.인터럽트()?

메소드를 호출하는 이유Thread.currentThread.interrupt()캐치 블럭에서?

이것은 위엄을 유지하기 위해 행해진다.

당신이 잡으면InterruptedException그리고 그것을 삼키면, 당신은 본질적으로 어떤 상위 수준의 방법/계층들이 인터럽트를 알아차리지 못하게 된다.문제가 생길 수도 있어

전화해서Thread.currentThread().interrupt()스레드의 인터럽트 플래그를 설정하여 상위 수준의 인터럽트 핸들러가 이를 알아차리고 적절하게 처리할 수 있도록 하십시오.

Java Concursence in Practice는 7.1.3장: Response to Interruption에서 이에 대해 자세히 설명한다.그 규칙은 다음과 같다.

스레드의 중단 정책을 구현하는 코드만이 중단 요청을 수용할 수 있다.범용 태스크 및 라이브러리 코드는 중단 요청을 절대 삼켜서는 안 된다.

이 코드 샘플은 상황을 좀 더 명확하게 하는 것 같아.작업을 수행하는 클래스:

public class InterruptedSleepingRunner implements Runnable {
    @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) {
            Thread.currentThread().interrupt();
        }
    }
}

Main클래스:

public class InterruptedSleepingThreadMain {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new InterruptedSleepingRunner());
        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

장기간(예: 입력을 위해) 기다리는 스레드를 중지하려면 어떻게 해야 하는가?

이 기술이 작동하려면 인터럽트 예외를 포착하고 이를 처리할 준비가 되어 있지 않은 모든 방법이 해당 예외를 즉시 재인증하는 것이 중요하다.우리는 재탕보다는 재탕이라고 말하는데, 왜냐하면 예외를 재탕하는 것이 항상 가능한 것은 아니기 때문이다.인터럽트를 잡는 방법인 경우예외는 이 (체크된) 예외를 발생시키도록 선언되지 않았다. 그러면 다음과 같은 계정으로 "재파괴"되어야 한다.

Thread.currentThread().interrupt();

이렇게 하면 스레드가 인터럽트된 스레드를 다시 들어올릴 수 있음가능한 한 빨리 예외로 하자.

나는 그것을 나쁜 관행이나 적어도 약간은 위험하다고 생각할 것이다.일반적으로 상위 레벨의 방법은 차단 작업을 수행하지 않으며 절대 볼 수 없다.InterruptedException거기. 방해를 하는 모든 곳에서 그것을 가린다면, 당신은 결코 그것을 얻을 수 없을 것이다.

에 대한 유일한 근거.Thread.currentThread.interrupt()다른 방식으로 다른 예외를 제기하거나 인터럽트 요청을 신호로 표시하지 않음(예: 설정)interrupted스레드의 메인 루프에 있는 로컬 변수)는 과거처럼 예외를 가지고는 정말 아무것도 할 수 없는 상황이다.finally블록

페테르 툴뢰크의 대답을 참조하라.Thread.currentThread.interrupt()전화를 걸다

Java 문서에서 참조

대기(), 결합(), 절전(긴 길이)의 호출에서 이 스레드가 차단되면 인터럽트 상태가 지워지고 인터럽트 상태가 수신됨예외.

I/O 작업에서 이 스레드가 차단되면 스레드의 인터럽트 상태가 설정되고 스레드가 ClosedBy를 수신하게 된다.인터럽트Exception.

이 스레드가 선택기에서 차단되면 스레드의 인터럽트 상태가 설정되고 선택 작업에서 즉시 반환된다.

이전 조건이 유지되지 않으면 이 스레드의 인터럽트 상태가 설정된다.

따라서 @Ajay George Aswer to I/O operation 또는 그냥 sysout에서 sleepBabySleep() 방법을 변경하면 프로그램을 중지하기 위해 상태를 다시 설정할 필요가 없다.(BTW, 그들은 인터럽트(Interrupted)조차 던지지 않는다.예외)

@Péter Török가 말한 것처럼 => 이것은 상태를 유지하기 위해 하는 것이다. (그리고 인터럽트를 던질 방법에 대해서는 특히 그렇다.예외)

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

반응형