static sleep(long)
, static yield()
: 다른 쓰레드에게 적용될 수 없고, 쓰레드 자기 자신에게만 호출 가능static sleep()
static void sleep(long millis)
- 천분의 일초 단위
static void sleep(long millis, int nanos)
- 천분의 일초 + 나노초
InterruptedException
이 발생하면 깨어남try{
Thread.sleep(1, 500000); //쓰레드를 0.0015초 동안 멈추게 한다.
// 0.001 + 0.0005
} catch(InterruptedException e) {}
예외처리를 안하면, 누군가 깨워서 얘가 throw new InterruptedException
하게 된다. 그리고 어차피 필수예외임
✨귀찮으니 메소드를 따로 만들어 호출한다.
void delay(long millis) { try{ Thread.sleep(millis); } catch(InterruptedException e) {} }
-> 호출
delay(15);
static
: 특정 쓰레드를 지정해서(예: t1.sleep() (X)) 멈추게 하는 것은 불가능하다. (Thread클래스이름.sleep() (O)) ex13_08
public class Ex13_08 {
public static void main(String[] args) {
Thread08_1 t1 = new Thread08_1();
Thread08_2 t2 = new Thread08_2();
t1.start();
t2.start();
delay(2*1000);
//sleep 안하면 아래 문장이 맨위에 바로 실행됨
System.out.print("<<main 종료>>");
}
static void delay(long millis) {
try {
Thread.sleep(millis); //***Thread.sleep()!!
} catch (InterruptedException e) {}
}
}
class Thread08_1 extends Thread{
public void run() {
for(int i=0; i<100; i++)
System.out.print("-");
System.out.print("<<t1 종료>>");
}
}
class Thread08_2 extends Thread{
public void run() {
for(int i=0; i<100; i++)
System.out.print("|");
System.out.print("<<t2 종료>>");
}
}
--------|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||---------||||||||||||||||--|||||||||||----<<t2 종료>>-----------------------------------------------------------------------------<<t1 종료>><<main 종료>>
main쓰레드가 2초동안 자는동안 다른 쓰레드들이 일한다.
2초가 지나면 main실행
시간종료 : time up
누가 깨우기 : interrupted()
static boolean interrupted()
- ✨
static
-> ✨Thread.interrupted()
- 현재 쓰레드의 interrupted상태를 알려주고, ✨
false
로 초기화
void interrupt()
- 쓰레드의 interrupted상태를 false -> ✨
true
로 변경- 대기상태(WAITING)인 쓰레드를 실행대기 상태(RUNNABLE)로 만든다.
boolean isInterrupted()
- 쓰레드의 interrupted상태를 반환한다.
ex13_09
import javax.swing.JOptionPane;
class Ex13_09 {
public static void main(String[] args) throws Exception {
Thread09_1 th1 = new Thread09_1();
th1.start();
System.out.println("isInterrupted(): " + th1.isInterrupted());
String input = JOptionPane.showInputDialog("계속하시려면 아무 키나 눌러주세요.");
System.out.println(input + ": 계속합니다.");
th1.interrupt(); // th1의 interrupted상태 -> true 로
System.out.println("ㅁisInterrupted(): "+th1.isInterrupted());
//***interrupted()는 static!! 자기자신Thread만!!
//main쓰레드가 interrupt되었는지 확인
System.out.println("메인:interrupted(): "+Thread.interrupted());
//main을 interrupt()하지 않았으니 당연 false
System.out.println("ㄴisInterrupted(): "+th1.isInterrupted());
System.out.println("메인 종료");
}
}
//***게임에서 "계속 하시겠습니까?" 카운트다운하는 알고리즘
class Thread09_1 extends Thread {
public void run() {
int i = 10;
// 아직 시간 남아있고 && interrupted상태가==false이면(==interrupt();호출 안했으면)
while (i != 0 && !isInterrupted()) {
try {
sleep(1000);
System.out.println(i--);
} catch (InterruptedException e) {
interrupt();
}
// for (long x = 0; x < 2500000000000L; x++); // 시간지연
}
//위에서 th1.interrupt()했어도 false다. 왜??
//????쓰레드가 잠들어있는 동안 th1.interrupt호출되면 예외가 발생하면서 interrupted상태가 false로 초기화되기 때문!!
//***따라서 catch에 interrupt()호출로 다시 true로 만들어야 한다.
System.out.println("isInterrupted(): " + this.isInterrupted());
//**th1쓰레드가 interrupt되었는지 확인하려면 여기다가, true, 그리고 false로 초기화
System.out.println("interrupted(): " + Thread.interrupted());
System.out.println("isInterrupted(): " + this.isInterrupted());
System.out.println("interrupted(): " + Thread.interrupted());
//셋다 this.나 Thread. 안해도 된다.
System.out.println("카운트다운이 종료되었습니다.");
}
}
isInterrupted(): false
10
9
8
7
yes: 계속합니다.
ㅁisInterrupted(): true
isInterrupted(): true
메인:interrupted(): false
ㄴisInterrupted(): false
메인 종료
interrupted(): true
isInterrupted(): false
interrupted(): false
카운트다운이 종료되었습니다.
솔직히 이해안가고, 카운트다운할 때 저렇게 쓴다라고만 알자!!