
interrupt : 실행 불가 상태에 있는 애들을 대기열로 돌아오게 한다.
(Not runnable -> Runnable)
→ 실행 불가 상태에 있는 애들을 대기열로 돌리는 문법적인 방식 : 예외를 발생시켜서 한다.
→ 실행 불가 스레드 일때만 InterruptedException가 발생한다.
→ 실행 중인 스레드에 interrupt을 해도 아무 일도 안 일어난다.
단지, 받았다는 정보는 기억하고 있는다.
정보를 받은 기억이 있으면 sleep, wait를 해도 바로 대기열로 돌아오고(무효화) 이때 정보를 받은 기억을 초기화 한다.
→ 미리 interrupt 받은 스레드는 실행 불가 상태가 되면 바로 대기열로 돌아온다.
class Dummy{
public synchronized void todo() {
try {
System.out.println("t1(run) : " + Thread.currentThread().isInterrupted());
System.out.println("start....");
wait();
}catch (InterruptedException e) {
//실행 할 때 대기열로 간다.
System.out.println("interrupted!!!");
System.out.println("t1(run) : " + Thread.currentThread().isInterrupted());
}
}
}
public class IntereuptEx {
public static void main(String[] args) {
final Dummy d = new Dummy();
Thread t1 = new Thread() {
@Override
public void run() {
d.todo();
System.out.println("i'm dead");
}
};
t1.start();
try {
Thread.sleep(3000);
}catch (Exception e) {
}
t1.interrupt();
System.out.println("t1(main) : " + t1.isInterrupted());
}
}
→ 위 코드에서 try-catch 부분이 없다면 start에서 멈추고, 이를 데드락이라고 한다.
1) interrupt() : 해당 스레드에게 인터럽트를 건다.
2) thread.isInterrupted() : 스레드가 인터럽트를 받았는지 확인한다.
3) interrupted() : 현재 스레드(static)가 인터럽트 받았는지 확인하고 상태를 초기화 한다.
public class IntereuptTest2 {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
try {
System.out.println("try - isInterrupted : " + isInterrupted());
// 인터럽트 받은 기록이 초기화됨(false)
// 실행하면 정보를 받았다고 true로 나오고 바로 초기화시킴
// 인터럽트를 미리 날리면 sleep, wait, join 등이 안된다.
System.out.println("try - interrupted : " + Thread.interrupted());
System.out.println("ok");
Thread.sleep(4000);
}catch (InterruptedException e) {
System.out.println("catch - isInterrupted : " + isInterrupted());
}
}
};
t.start();
t.interrupt();
System.out.println("isInterrupted : " + t.isInterrupted());
try {
Thread.sleep(1000);
}catch (Exception e) {}
System.out.println("isInterrupted : " + t.isInterrupted());
}
}