interrupt()
대기상태( waiting)인 쓰레드를 실행대기 상태로 만든다.
잠자거나, 쉬고있거나 등등
진행 중인 쓰레드의 작업이 끝나기 전에 취소시켜야 할 때가 있다. 예를 들어 큰 파일을 다운로드 받을때 시간이 너무 오래 걸리면 중간에 다운로드를 포기하고 취소할 수있어야 한다.
interrupt는 쓰레드에게 작업을 멈추라고 요청하는 것이다.
단지 멈추라고 요청만 하는 것일 뿐 쓰레드를 강제로 종료시키지는 못한다!
void interrupt() //쓰레드의 interrypted상태를 false에서 true로 변경,
boolean isInterrupted() //쓰레드의 interrupted 상태를 반환
static boolean interrupted() // 현재 쓰레드의 interrupted상태를 알려주고, false로 초기화
static boolean과 boolean 경우 만약 내가 잠을 자다고 일어나는지, 누군가 나를 깨워서 일어났는지 알수있지만, static은 그걸 false로 초기화 시켜준다.
이걸 왜쓰는가? 계속 true 일경우 어느상태인지 모른다. 그럴때 isInterrupted로 상태를 알고 그리고 다시 끄기에는 번거롭다.
그래서 true 인걸 이미 가정하고 사용한다면 좀 편하게 쓸수 있다.
이것을 다운로드로 예를 들면 이해하기 쉬울것이다.
파일다운로드중에 취소버튼을 누르면 종료되도록 하는것이다.
쓰레드가 어떤 작업을 하다가 내가 작업을 중단시키거나, 다시 작업 시키는것 = interrupt()
예제를 통해 살펴보자
package ch13.Thread;
import javax.swing.JOptionPane;
public class ThreadEx13 {
public static void main(String[] args) {
// TODO Auto-generated method stub
ThreadEx13_1 t1 = new ThreadEx13_1();
t1.start();
String input = JOptionPane.showInputDialog("아무거나 입력해주세요.");
System.out.println("입력하신 값은 : " + input);
t1.interrupt();
System.out.println("isInterrupted() : " + t1.isInterrupted());
}
}
class ThreadEx13_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("카운트다운이 종료되었습니다.");
}
}
사용자의 입력이 끝나자 interrupt()에 의해 카운트 다운이 중간에 멈추었다.
package ch13.Thread;
import javax.swing.JOptionPane;
public class ThreadEx13 {
public static void main(String[] args) {
// TODO Auto-generated method stub
ThreadEx13_1 t1 = new ThreadEx13_1();
t1.start();
boolean b = true;
while (b) {
System.out.println(b);
String input = JOptionPane.showInputDialog("아무거나 입력해주세요.");
System.out.println("입력하신 값은 : " + input);
if (input.equals("stop")) {
t1.interrupt();
b = false;
}
System.out.println("isInterrupted() : " + t1.isInterrupted());
}
}
}
class ThreadEx13_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("카운트다운이 종료되었습니다.");
}
}
좀더 박진감을 위하여 while과 if문을 넣어 stop이 나올떄까지 반복시켰다.
게임에서 카운트다운 계속 되고있는데 계속하시겠습니까? yes 나 no 할때까지 물어보고 시간은 계속내려가고
이런 게임을 원했다. 그래서 한번 구현해 주었다.
그리고 메서드들을 전부 활용하기 위해 조금더 수정을 해보았다.
public static void main(String[] args) {
// TODO Auto-generated method stub
ThreadEx13_1 t1 = new ThreadEx13_1();
t1.start();
boolean b = true;
while (b) {
System.out.println(b);
String input = JOptionPane.showInputDialog("아무거나 입력해주세요.");
System.out.println("입력하신 값은 : " + input);
if (input.equals("stop")) {
t1.interrupt();
b = false;
}
System.out.println("isInterrupted() : " + t1.isInterrupted());
}
System.out.println("isInterrupted() : " + t1.isInterrupted());
System.out.println("Interrupted() : " + t1.interrupted());
System.out.println("Interrupted() : " + Thread.interrupted());
}
}
하단에 보면 t1.interrupted() 와 Thread.interrupted()를 작성했다.
설명을 위해 콘솔창과 코드가 모두 나오도록하였다.
티원인터럽티드에 컴파일링 오류가 있다
이이유는 인터럽티드 메서드가 static 성질을 가지고있어서 현재 위치에 있는 쓰레드-main쓰레드를
나타내준다. 그래서 오류가나고, Thread.인터럽티드해주면 된다.
결과도 둘다 동일하다.
해당 쓰레드클래스에서 실행시키고 싶다면
class ThreadEx13_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("Interrupted() : " + Thread.interrupted());
System.out.println("isInterrupted() : " + this.isInterrupted());
System.out.println("카운트다운이 종료되었습니다.");
}
}
아래와 같이 나타나도록 해준다면 알수있다.
그런데 시간초를 지금은 for문의 계산속도를 지연시킴으로써 딜레이를 만들었다.
그러면 sleep으로 시간초 딜레이를 만들어서 돌린다면 결과값은 같을까?
동일한 에제에 해당 딜레이부분만 수정해 주었다.
package ch13.Thread;
import javax.swing.JOptionPane;
public class ThreadEx14 {
public static void main(String[] args) {
// TODO Auto-generated method stub
ThreadEx14_1 t1 = new ThreadEx14_1();
t1.start();
String input = JOptionPane.showInputDialog("아무거나 입력해주세요.");
System.out.println("입력하신 값은 : " + input);
t1.interrupt();
System.out.println("isInterrupted() : " + t1.isInterrupted());
}
}
class ThreadEx14_1 extends Thread {
public void run() {
int i = 10;
while (i != 0 && !isInterrupted()) {
System.out.println(i--);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
System.out.println("카운트가 종료되었습니다.");
}
}
그러나 결과는 충격이었다.
카운트가 종료되지 않았다.
그 이유는 Thread.sleep(1000)에서 InterruptedException 이 발생 했기 때문이다.
엥? 이게 뭐야?
sleep() 에 의해 쓰레드가 잠시 멈춰 있을때 interrupt()를 호출하면 InterruptedExceoption이 발생되고
쓰레드의 interrupted 상태는 false로 자동 초기화 된다...
interrupt() 로 인한 예외가 발생했을떄... 그때도 예외처리를 예외처리문 내에서 interrupt()로 처리해라..
class ThreadEx14_1 extends Thread {
public void run() {
int i = 10;
while (i != 0 && !isInterrupted()) {
System.out.println(i--);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
this.interrupt();
}
}
System.out.println("카운트가 종료되었습니다.");
}
}
이렇게 말이다.
그래도 바로바로 적용되니까 뿌듯하다
'JAVA공부 > 2-쓰레드' 카테고리의 다른 글
쓰레드 제어문(4) (0) | 2021.10.14 |
---|---|
쓰레드 제어문(3) (0) | 2021.10.14 |
쓰레드 제어문(1) (0) | 2021.10.13 |
쓰레드 제어문(1) (0) | 2021.10.13 |
데몬 쓰레드와 쓰레드의 상태(실행제어) (0) | 2021.10.12 |
댓글