Right now do !

[JAVA] concurrent programming - isInterrupted() VS interrupted()

by 지금당장해

 JAVA concurrent의 번외편으로 인터럽트를 검사하는 interrupted, isInterrupt 두 함수에 대해서 간략히 다루고자 한다. 살짝 불만부터 늘어 놓자. 도대체 왜 헷갈리게 이름이 비슷한 함수를 정적 함수와 인스턴스 함수 두 개로 분리해서 제공하는지? 이렇게 불만을 늘어 놓은 계기를 마련해준 두 함수의 차이점에 대해 알아보자.

 

 thread control 편에서 interrupt()와 InterruptedException 그리고 isInterrupt() 함수에 대해서 다루었다. 아차 그런데 빼 놓은 것이 생각이 났다 Thread Class에 정적으로 구현되어 있는 interrupted() 함수이다. 현재 thread의 interrupt상태를 검사하는 함수라는 측면에서는 같은 작용을 하는 것으로 보인다. 하지만 아주 중요한 차이 점이 존재한다. 다음은 이와 관련된 Oracle의 JAVA API Doc 의 내용을 발췌한 글이다. 

Tests whether the current thread has been interrupted. The interrupted status of the thread is cleared by this method. In other words, if this method were to be called twice in succession, the second call would return false (unless the current thread were interrupted again, after the first call had cleared its interrupted status and before the second call had examined it).

 

https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupted()

 

Thread (Java Platform SE 7 )

Allocates a new Thread object so that it has target as its run object, has the specified name as its name, and belongs to the thread group referred to by group, and has the specified stack size. This constructor is identical to Thread(ThreadGroup,Runnable,

docs.oracle.com

JAVA Doc에 필자가 강조한 부분을 보자. interrupted()함수 자신이 호출후에 무조건 false로 변경한다. 이 함수는 interrupt()가 여러번 호출될 경우에 사용할 수 있는 검사 함수이다. 다음 예제 코드와 결과를 통해 이를 확인하자.

@Test
public void threadStaticInterruptedTest () {

    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            while (!Thread.interrupted()) {
                System.out.println(
                    String.format("%s >>> thread is Running"
                        , Thread.currentThread().getName()));
                ThreadUtil.sleep(10);
            }
            System.out.println(
                String.format("%s >>> thread is Running, but terminate shortly. anyway current thread interrupted() is %s"
                    , Thread.currentThread().getName(), Thread.interrupted()));
        }
    });

    t1.start();
    ThreadUtil.sleep(100);
    t1.interrupt();

    try {
        t1.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

결과 >>>

Thread-4 >>> thread is Running
Thread-4 >>> thread is Running
Thread-4 >>> thread is Running
Thread-4 >>> thread is Running
Thread-4 >>> thread is Running
Thread-4 >>> thread is Running, but terminate shortly. anyway current thread interrupted() is false

Thread.interrupted() == true 조건으로 함수를 loop를 탈출 했는데 바로 다음 이 함수를 실행해보면 true가 아닌 false를 출력했다. 

 이제 Thread의 인스턴스 함수인 isInterrupted() 함수를 살펴볼 차례다. interrupted() 함수와 차이점은 한번 interrupt()함수에 호출이 유효하게 적용이 되면 상태가 계속 유지된다는 것이다. "유효하게 적용"이라는 표현에 주목하자. 이는 상황에 따라서 interrupt()가 유효하지 않을수도 있다는 뜻이다. wait(), sleep(), join()등으로 thread가 휴식 상태에 들어 가 있는 경우에는 interrupt()에 의해 interrupted(), isInterrupted()가 true로 변경되지 않고 InterruptException이 발생함을 함축한 표현이다.

 

다음 예제는 interrupted()함수를 설명한 예제와 반대의 결과를 가져오는 isInterrupted()를 사용한 코드이다. 

@Test
public void threadInstanceIsInterruptedTest () {

    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println(
                    String.format("%s >>> thread is Running", Thread.currentThread().getName()));
                ThreadUtil.sleep(10);
            }

            System.out.println(
                String.format("%s >>> thread is Running, but terminate shortly. anyway current thread isInterrupted() is %s"
                    , Thread.currentThread().getName(), Thread.currentThread().isInterrupted()));
        }
    });

    t1.start();
    ThreadUtil.sleep(100);
    t1.interrupt();


    try {
        t1.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}
Thread-4 >>> thread is Running
Thread-4 >>> thread is Running
Thread-4 >>> thread is Running
Thread-4 >>> thread is Running
Thread-4 >>> thread is Running
Thread-4 >>> thread is Running
Thread-4 >>> thread is Running, but terminate shortly. anyway current thread isInterrupted() is true

 비정상적인 상황이 발생하여 thread를 멈춰야 할 때  thread를 종료하는 용도로 interrupt() 함수를 사용한다. 그리고 이 thread를 TERMINATION 상태로 끝내는 상황이면 굳이 Thread.interrupted()을 사용할 필요가 없다. 그러나 interrupt() 호출 되었음에도 불구하고 해당 thread를 종료시키지 않고 계속 진행시켜야 할 경우 interrupted()로 thread에 interrupt 상태를 확인 할 수 있을 것이다.

블로그의 정보

지금 당장 해!!!

지금당장해

활동하기