ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Thread] InterruptedException과 인터럽트 상태
    java/Thread 2022. 6. 12. 16:18

    스레드의 인터럽트 메카니즘과 인터럽트 상태에 대하여 정리했다.

    인터럽트라는 단어에서 뭔가 중단하다.방해하다라는 느낌이 애매해서 이해하기 어려웠던 것 같다.

    특정 스레드에 인터럽트를 건다라는 의미 = 스레드가 일시정지 상태인 경우 또는  일시정지에 들어가려는 스레드인 경우 쉬지 못 하게 하는 기능이다.

    스레드 인터럽트 메카니즘을 이해하기 위해 아래의 개념들을 보자.


    -- 스레드 인터럽트 플래그(상태)

    스레드의 인터럽트 상태는 인터럽트 예외(InterruptedException)와 연관있는 플래그이다.

     

    // 1. thread변수에 해당하는 스레드의 인터럽트 상태를 체크한다.(인터럽트 상태를 변경하지 않고 확인만 한다)
    thread변수.isInterrupted(); 

    // 2. 현재 스레드의 인터럽트 상태를 리턴한 뒤 인터럽트 상태를 false로 초기화한다.(인터럽트 상태 확인 후 인터럽트 상태가 자동으로 false로 변경됨)
    Thread.interrupted(); 

    // 3. workerThread에 인터럽트를 건다.
    //start되지 않았거나, 이미 작업이 끝난 스레드의 경우에는 인터럽트를 걸어도 스레드의 인터럽트 플래그는 true로 변하지 않고 false를 유지한다.
    workerThread.interrupt(); 

     

    1,2 메서드는 인터럽트 상태를 확인해보기 위해 유용하게 사용하며, 3번은 특정 스레드에 인터럽트를 걸 때 사용한다.


    -- 인터럽트 예외(InterruptedException)

     

    InterruptedException 예외는 InterruptedException을 던지는 스레드의 sleep()등의 메서드 호출시 발생할 수 있다.

     

    InterruptedException이 발생하는 경우

    1. sleep()메서드가 호출상태(대기상태인 도중)에서 인터럽트 상태가 true(누군가 이 스레드에 인터럽트 걸음)로 되는 경우

    2. 스레드의 인터럽트 상태가 true(누군가 이 스레드에 인터럽트를 걸은 상태에서)인 상태에서 작업 스레드에 제어권이 넘어와서 sleep()메서드가 호출시작됬을때

     

    InterruptedException이 발생한 후 스레드의 인터럽트 상태는 자동으로 false로 변경된다

    -> catch문에서 인터럽트 상태를 확인해보면 false를 확인 할 수 있다.

     

    인터럽트 예외를 확인해보기 전에 try- catch에서 마주쳤던 문제를 기록해놨다.


    아래의  try블록 내부에서는 InterruptedException이 절대 발생할 수 없다.(InterruptedException을 던지는 메서드가 없어서)

    따라서 catch문에서는 이 예외는 절대 발생할 수 없다고 필요없다고 지우라는 컴파일 에러가 난다.


    -- 인터럽트 예외 확인 예제

     

    메인스레드에서 원하는 시점에 작업 스레드에 인터럽트를 걸수 있게 하기 위해 다이얼로그 창을 통해 아무 버튼을 클릭하는 시점에 작업 스레드에 인터럽트가 걸린다.

     

    작업스레드에서는 윗부분의 InterruptedException이 발생하는 1,2의 경우를 확실히 분간하기 위해 Thread.sleep을 5초로 설정하고 작업스레드의 작업이 최대한 오래걸리게 반복을 설정하였다.(pc의 성능에 따라 작업스레드의 문자출력이 너무 빨리 끝난다 싶으면 반복을 늘리자)

     

    package thread;
    
    import javax.swing.JOptionPane;
    
    //InterruptedException이 발생하는 경우
    //1. 인터럽트가 걸려있는 상태(인터럽트 상태가 true인 상태)에서 sleep()메서드가 호출되는 경우
    //2. sleep메서드가 호출된 상태에서 인터럽트가 걸리는 경우(인터럽트 상태가 true)가 되는 경우 
    public class InterruptExceptionAndSleep {
    
    	public static void main(String[] args) {
    
    		Thread a = new TestThread();
    		a.start();
    
    		while (true) {
    			String input = JOptionPane.showInputDialog("인터럽트를 거시겠습니까?");
    			a.interrupt();
    			System.out.println("main스레드에서 a스레드 인터럽트 상태 확인 " + a.isInterrupted());
    
    		}
    
    	}
    }
    
    class TestThread extends Thread {
    	public void run() {
    		String tab = "\t\t\t\t\t\t";
    		while (true) {
    			try {
    				System.out.println(tab + "자기자신에서 인터럽트 상태 확인 " + this.isInterrupted());
    				System.out.println(tab + "try1- sleep상태");
    				Thread.sleep(5000);
    				System.out.println();
    				System.out.println(tab + "try2- sleep에서 깨어남");
    				System.out.println(tab + "try3- 작업중....빈 반복문 수행");
    				for (long l = 0; l < 30000000L; l++) {
    					System.out.println("-");
    				}
    				System.out.println(tab + "try4- 작업 끝");
    
    			} catch (InterruptedException e) {
    				System.out.println(tab + "InterruptedException 발생");
    				System.out.println(tab + "인터럽트 상태: " + this.isInterrupted());
    			}
    		}
    
    	}
    }

    결과

     

    1. 작업 스레드가 확실히 5초 대기 상태로 바로 들어갈 때 다이얼로그를 누름 ->  작업 스레드 인터럽트를 검

    -> 작업 스레드가 sleep()상태에서 바로 InterruptedException이 발생한다.

     

    2. 작업 스레드의 "-"를 출력하는 상태에서 다이얼로그를 누름 -> 작업 스레드 인터럽트를 검 ->  sleep() 메서드는 현재 "-"출력작업이 끝난 뒤 다음 while 반복에서 호출되므로 작업을 모두 끝내고 sleep메서드가 호출될 때 InterruptedException이 발생한다. 

    //try2- sleep에서 깨어남

    //try3- 작업중....빈 반복문 수행

    //main스레드에서 a스레드 인터럽트 상태 확인 true

    (문자열 출력 때문에 위의 출력이 사라졌다.위의 출력이 포함된다.)

    작업중에 인터럽트가 걸리면  sleep()메서드를 만나기전인 자기가신에서 인터럽트 상태 확인에서 true인 것을 확인할 수 있고 sleep상태에 들어가자마자 InterruptedException이 발생하는 것을 확인할 수 있다.


    InterruptedException을 발생시켜 catch블록에서 스레드를 제어할 수 있다.

    'java > Thread' 카테고리의 다른 글

    Thread(5) synchronized를 이용한 스레드 동기화  (0) 2021.06.08
    [Thread] Daemon Thread  (0) 2021.05.27
    [Thread] Thread, ThreadGroup  (0) 2021.05.27

    댓글

Designed by Tistory.