Ch13-22~25. sleep()
0. 목차
Chapter13. 쓰레드
Ch13 - 22. sleep()
Ch13 - 23. sleep() 예제
Ch13 - 24. interrupt()
Ch13 - 25. interrupt() 예제
Ch13 - 22. sleep()
▶ sleep()이란?
▷ 현재 쓰레드를 지정 된 시간 동안 멈추에 함
▷ static 메서드 : 자기 자신에게만 동작
static void sleep(long millis) // 잠 잘 시간을 설정, 3000 = 3초
static void sleep(long millis, int nanos)
- millis = 1/1000초 = 10-3
- nanos = 1/1000000000초 = 10-9
▷ 특정 쓰레드를 지정하여 멈추게 하는 것 불가능
try {
th1.sleep(1, 500000) // th1을 sleep() 시킨다?, 에러는 안나지만 오해할 수 있음
} catch(InterruptedException e) { }
// ↓↓↓↓ 변경 ↓↓↓↓
try {
Thread.sleep(1, 500000) // Thread를 적어 줌
} catch(InterruptedException e) { }
▶ sleep()을 깨우는 방법
▷ InterruptedException 발생 시 깨어남
- sleep() code
// sleep() = InterruptedException을 필수로 갖고있는 메서드 public static native void sleep(long millis) throws InterruptedException;
- InterruptedException code
// InterruptedException = Exception을 상속받음 public class InterruptedException extends Exception
- sleep() 사용 시, try-catch문 반드시 작성
try { Thread.sleep(1, 500000) // 쓰레드를 0.0015초 동안 멈춤 } catch(InterruptedException e) { } // ↓↓↓↓ 계속 만들지 않고 메서드에 담을 수 있음 ↓↓↓↓ static void delay(long millis) { try { Thread.sleep(millis) } catch(InterruptedException e) { } } // ↓↓↓↓ delay 메서드를 사용하려면? ↓↓↓↓ delay(15); // 0.0015초 동안 멈춤
- 0.0015초 동안 try에서 throw new InterruptException이 발생하면
- catch문 실행하여 sleep() 깨움
- 0.0015초 동안 try에서 throw new InterruptException이 발생하면
▷ time up
- 시간 종료
Ch13 - 23. sleep() 예제
▶ 2초 잠든 후 main 메서드 종료
▷ 직접 sleep 코드 작성하여 사용
class Ex13_8 {
public static void main(String args[]) {
ThreadEx8_1 th1 = new ThreadEx8_1();
ThreadEx8_2 th2 = new ThreadEx8_2();
th1.start(); th2.start();
try {
Thread.sleep(2000); // th1.sleep() 이라 적지 않음, 오해 만들지 않기
} catch(InterruptedException e) {}
System.out.print("<<main 종료>>");
} // main
}
class ThreadEx8_1 extends Thread {
public void run() {
for(int i=0; i < 300; i++) System.out.print("-");
System.out.print("<<th1 종료>>");
} // run()
}
class ThreadEx8_2 extends Thread {
public void run() {
for(int i=0; i < 300; i++) System.out.print("|");
System.out.print("<<th2 종료>>");
} // run()
}
// console
--|||||||||||||||||||||||||||||||||||||||||||||||---|||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||--------------------------------------||||||||||||||||||||||||-----
-----------------------------------|||||||||||||||||||||----------|||||||||||||||||||||||||
||||||||||---------------------------------------------------------------------------------
-----------------------------------------------||||||||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||--------------------------------------------------------------|
||||||-|||||||||||||||||||||||||||||||<<th2 종료>>----------------<<th1 종료>><<main 종료>>
<<th2 종료>> → <<th1 종료>> -2초 후→ <<main 종료>>
▷ 메서드 생성하여 호출하여 사용
class Ex13_8 {
public static void main(String args[]) {
ThreadEx8_1 th1 = new ThreadEx8_1();
ThreadEx8_2 th2 = new ThreadEx8_2();
th1.start(); th2.start();
delay(2000);
System.out.print("<<main 종료>>");
} // main
static void delay(long millis) {
try {
Thread.sleep(millis);
} catch(InterruptedException e) { }
}
}
Ch13 - 3. interrupt()
▶ interrupt()란?
▷ 대기 상태(WAITING)인 쓰레드를 실행 대기 상태(RUNNABLE)로 만듦
- 대기 상태 : sleep(), join(), wait()
▶ interrupt()의 관련 메서드
▷ void interrupt()
- 쓰레드의 interrupted 상태를 false에서 true로 변경
▷ boolean isInterrupted()
- 쓰레드의 interrupted 상태를 반환
- 잠을 자고 있었는데 누가 깨워서 일어났는지, 다 자고 일어났는지 확인 가능
▷ static boolean interrupted()
-
현재 쓰레드의 interrupted 상태를 알려주고, false로 초기화
-
Thread code
class Thread { ... boolean interrupted = false; // 자는 중 ... boolean isInterrupted() { return interrupted; } // isInterrupted는 false로 초기화 안함, 계속 true상태 유지 boolean interrupt() { interrupted = true; } // interrupt() 호출하면 잠 깨니까 true }
▷ 예시1
public static void main(String[] args) {
ThreadEx13 th1 = new ThreadEx13();
th1.start();
...
th1.interrupt(); // interrupt() 호출 시, interrupted 상태가 true가 됨, 잠 깸
System.out.println("isInterrupted() : " + th1.isInterrupted());
}
// console
isInterrupted() : true // 깼으니까 true
▷ 예시2
- 다운로드 중 취소 버튼 클릭 → interrupt() 발생
class ThreadEx13 extends Thread { public void run() { ... // download를 수행 while(downloaded && !isInterrupted()) { ... } } }
- 취소 클릭 시,
isInterrupted
상태 :false → true
!isInterrupted()
이므로 정확히isInterrupted
상태 :!false → !true
!false → !true : true → false
- 취소 클릭 시,
Ch13 - 3. interrupt() 예제
▶ boolean isInterrupted()
▷ th1.isInterrupted()
▷ th1.interrupt() → th1.isInterrupted()
▷ th1을 깨우고 상태 반환
▷ 깨웠으니까 th1.isInterrupted() = true 반환
import javax.swing.JOptionPane;
class Ex13_9 {
public static void main(String[] args) throws Exception {
ThreadEx9_1 th1 = new ThreadEx9_1();
th1.start();
String input = JOptionPane.showInputDialog("아무 값이나 입력하세요.");
System.out.println("입력하신 값은 " + input + "입니다.");
System.out.println("isInterrupted():"+ th1.isInterrupted());
th1.interrupt(); // interrupt()를 호출 시 interrupted = true
System.out.println("isInterrupted():"+ th1.isInterrupted());
System.out.println("isInterrupted():"+ th1.isInterrupted());
}
}
class ThreadEx9_1 extends Thread {
public void run() {
int i = 10;
while(i!=0 && !isInterrupted()) {
System.out.println(i--);
for(long x=0;x<2500000000L;x++); // 시간 지연
}
System.out.println("카운트가 종료되었습니다.");
}
}
// console
10
9
8
입력하신 값은 1515입니다.
isInterrupted():false
isInterrupted():true
isInterrupted():true
카운트가 종료되었습니다.
▶ static boolean interrupted()
▷ static은 자기 자신만 깨울 수 있음
▷ th1.interrupted() → Thread.interrupted()
▷ Thread.interrupted() : 여기서 Thread는 현재 쓰레드, main 쓰레드
▷ interrupt로 깨운 건 th1, main 쓰레드는 깨운 적 없음
▷ Thread.interrupted() : 현재 쓰레드인 main 쓰레드를 interrupt 했는가?
import javax.swing.JOptionPane;
class Ex13_9 {
public static void main(String[] args) throws Exception {
ThreadEx9_1 th1 = new ThreadEx9_1();
th1.start();
String input = JOptionPane.showInputDialog("아무 값이나 입력하세요.");
System.out.println("입력하신 값은 " + input + "입니다.");
System.out.println("isInterrupted():"+ th1.isInterrupted());
th1.interrupt(); // interrupt()를 호출하면, interrupted상태가 true가 된다.
System.out.println("isInterrupted():"+ th1.isInterrupted());
System.out.println("isInterrupted():"+ th1.isInterrupted());
System.out.println("interrupted():"+ Thread.interrupted());
System.out.println("interrupted():"+ Thread.interrupted());
}
}
class ThreadEx9_1 extends Thread {
public void run() {
int i = 10;
while(i!=0 && !isInterrupted()) {
System.out.println(i--);
for(long x=0;x<2500000000L;x++); // 시간 지연
}
System.out.println("카운트가 종료되었습니다.");
}
}
// console
10
9
8
7
입력하신 값은 9999입니다.
isInterrupted():false
isInterrupted():true
isInterrupted():true
interrupted():false
interrupted():false
카운트가 종료되었습니다.
▶ th1에서 확인 해 보기
▷ this.isInterrupted() : this 쓰레드가 interrupt 된 상태
▷ Thread.interrupted() : 현재 쓰레드가 interrupt 했는가?
import javax.swing.JOptionPane;
class Ex13_9 {
public static void main(String[] args) throws Exception {
ThreadEx9_1 th1 = new ThreadEx9_1();
th1.start();
String input = JOptionPane.showInputDialog("아무 값이나 입력하세요.");
System.out.println("입력하신 값은 " + input + "입니다.");
th1.interrupt(); // interrupt()를 호출하면, interrupted상태가 true가 된다.
}
}
class ThreadEx9_1 extends Thread {
public void run() {
int i = 10;
while(i!=0 && !isInterrupted()) {
System.out.println(i--);
for(long x=0;x<2500000000L;x++); // 시간 지연
}
System.out.println("isInterrupted():"+ this.isInterrupted());
System.out.println("isInterrupted():"+ this.isInterrupted());
System.out.println("isInterrupted():"+ this.isInterrupted());
System.out.println("interrupted():"+ Thread.interrupted());
System.out.println("interrupted():"+ Thread.interrupted());
System.out.println("카운트가 종료되었습니다.");
}
}
// console
10
9
8
입력하신 값은 1515입니다.
isInterrupted():true
isInterrupted():true
isInterrupted():true
interrupted():true
interrupted():false
카운트가 종료되었습니다.
interrupted()
: 현재 쓰레드는 interrupt 됨true
반환interrupted()
는false
로 초기화 시켜 둠