예제1: 생산자스레드가 데이터를 만들면, 소비자스레드가 읽는다.
package ex05_wait_notify;
public class WaitNotifyExample {
public static void main(String[] args) {
DataBox dataBox = new DataBox();
ProducerThread producerThread = new ProducerThread(dataBox);
ConsumerThread consumerThread = new ConsumerThread(dataBox);
producerThread.start();
consumerThread.start();
}
}
실행결과:
ProducerThread가 생성한 데이터: Data-1
ConsumerThread가 읽은 데이터 : Data-1
ProducerThread가 생성한 데이터: Data-2
ConsumerThread가 읽은 데이터 : Data-2
ProducerThread가 생성한 데이터: Data-3
ConsumerThread가 읽은 데이터 : Data-3
package ex05_wait_notify;
public class DataBox {
private String data;
public synchronized String getData() {
if (this.data == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
String returnValue = data;
System.out.println("ConsumerThread가 읽은 데이터 : " + returnValue);
data = null;
notify();
return data;
}
public synchronized void setData(String data) {
if (this.data != null) {
try {
wait();
} catch (InterruptedException e) {
}
}
this.data = data;
System.out.println("ProducerThread가 생성한 데이터: " + data);
notify();
}
}
package ex05_wait_notify;
public class ProducerThread extends Thread {
private DataBox dataBox;
public ProducerThread(DataBox dataBox) {
this.setName("ProducerThread");
this.dataBox = dataBox;
}
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
String data = "Data-" + i;
dataBox.setData(data);
}
}
}
package ex05_wait_notify;
public class ConsumerThread extends Thread {
private DataBox dataBox;
public ConsumerThread(DataBox dataBox) {
this.setName("ConsumerThread");
this.dataBox = dataBox;
}
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
String data = dataBox.getData();
}
}
}
※ 스레드의 안전한 종료 - stop 플래그, interrupt()
- 경우에 따라서는 실행 중인 스레드를 즉시 종료할 필요가 있다.
- stop() 메소드
스레드 즉시 종료
스레드를 갑자기 종료하게되면 사용 중이던 자원들이 불안전한 상태로 남겨진다.
deprecated
- stop 플래그를 이용하는 방법
stop 플래그로 메소드의 정상 종료를 유도한다.
package ex06_stop;
public class StopFlagExample {
public static void main(String[] args) {
PrintThread1 printThread = new PrintThread1();
printThread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
printThread.setStop(true);
}
}
실행결과:
...
실행 중
실행 중
실행 중
실행 중
실행 중
실행 중
자원 정리
실행 종료
package ex06_stop;
public class PrintThread1 extends Thread {
private boolean stop;
public void setStop(boolean stop) {
this.stop = stop;
}
@Override
public void run() {
while (!stop) {
System.out.println("실행 중");
}
System.out.println("자원 정리");
System.out.println("실행 종료");
}
}
- interrupt() 메소드를 이용하는 방법
일시정지 상태일 경우 InterruptedException 발생
실행대기 또는 실행상태에서는 InterruptedException 발생x
일시정지 상태로만들지 않고 while문을 빠져나오는 방법
boolean status = Thread.interrupt();
boolean status = objThread.isInterrupted();
1초 스레드 종료 예제
package ex06_stop;
public class InterruptExample {
public static void main(String[] args) {
PrintThread2 printThread2 = new PrintThread2();
printThread2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
printThread2.interrupt();
}
}
package ex06_stop;
public class PrintThread2 extends Thread {
@Override
public void run() {
try{
while (true) {
System.out.println("실행 중");
Thread.sleep(1);
}
}catch (InterruptedException e){}
System.out.println("자원정리");
System.out.println("실행 종료");
}
}
리팩토링 버전:
package ex06_stop;
public class PrintThread2 extends Thread {
@Override
public void run() {
// try{
// while (true) {
// System.out.println("실행 중");
// Thread.sleep(1);
// }
// }catch (InterruptedException e){}
while (true) {
System.out.println("실행 중");
if (Thread.interrupted()) {
break;
}
}
System.out.println("자원정리");
System.out.println("실행 종료");
}
}
'자바' 카테고리의 다른 글
[스레드] 9. 스레드 그룹 (0) | 2022.05.01 |
---|---|
[스레드] 8. 데몬 스레드 (0) | 2022.05.01 |
[스레드] 6. 스레드 상태제어(1) (0) | 2022.04.24 |
[스레드] 5. 스레드 상태 (0) | 2022.04.24 |
[스레드] 4. 동기화 메소드와 동기화 블록 (0) | 2022.04.24 |