일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- squery
- 웹
- UI
- 자바
- 프로그래밍
- 오라클
- 공부
- Java
- javascript
- 공부를열심히
- 프로젝트
- orcle
- 주말이다..
- 객체지향프로그래밍
- 웹프로그래밍
- Project
- 객체지향
- 객제지향
- CSS
- DB
- Oracle
- ERWin
- 데이터베이스
- 객제지향프로그래밍
- 코딩
- html
- web
- sql
- 테이블
- jsp
Archives
- Today
- Total
햄찌개
JAVA - 쓰레드 - wait(), notify() 본문
자바의 최상위 클래스인 Object에는 몇 가지 메서드가 존재한다. 널리 쓰이는 toString()은 객체를 문자열로 표현할 때, hashCode()는 객체의 해시 값을 계산할 때 사용된다. 거의 사용되지 않고 가끔 IDE의 자동 완성 기능에서나 보게 되는 메서드들도 있으니 그것이 바로 wait(), notify(), notifyAll()이다. 이들의 동작을 간략히 정리하면 다음과 같다.
메서드 기능 비고
wait | 갖고 있던 고유 락을 해제하고, 스레드를 잠들게 한다. | 호출하는 스레드가 반드시 고유 락을 갖고 있어야 한다. 다시 말해, synchronized 블록 내에서 호출되어야 한다. |
notify | 잠들어 있던 스레드 중 임의로 하나를 골라 깨운다. | 호출하는 스레드가 반드시 고유 락을 갖고 있어야 한다. 다시 말해, synchronized 블록 내에서 호출되어야 한다. |
notifyAll | 호출로 잠들어 있던 스레드 모두 깨운다. | 호출하는 스레드가 반드시 고유 락을 갖고 있어야 한다. 다시 말해, synchronized 블록 내에서 호출되어야 한다. |
* wait()메서드 => 동기화 영역에서 락을 풀고 Wait-Set영역(공유객체별 존재)으로 이동시킨다.
*
* notify()또는 notifyAll()메서드 => Wait-Set영역에 있는 쓰레드를 꺠워서 실행할 수 있도록 한다.
* (notify()는 하나, notifyAll()은 Wait-Set에 있는 전부를 꺠운다.)
*
* => wait()과 notify(),notifyAll() 메서드는 동기화 영역에서만 실행할 수 있고,
* Object 클래스에서 제공하는 메서드 이다.
예제1) A가 B를 꺠우고 자로가고 B가 A를 꺠우고 자로가고 하다가 A가 B꺠우기전에 끝나서 B는 않끝남
package kr.or.ddit.basic;
public class T19_WaitNotifyTEst {
public static void main(String[] args) {
WorkObject workObj = new WorkObject();
ThreadA tha = new ThreadA(workObj);
ThreadB thb = new ThreadB(workObj);
tha.start();
thb.start();
}
}
// 공통으로 사용할 객체
class WorkObject {
public synchronized void methodA() {
System.out.println("methodA()에서 작입중...");
notify(); //대기실에 있는 놈 깨운다.
try {
wait(); //내가 대기실로 간다.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void methodB() {
System.out.println("methodB()에서 작입중...");
notify();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* WorkObject의 methodA()메서드만 호출하는 쓰레드
*/
class ThreadA extends Thread{
private WorkObject workObj;
public ThreadA(WorkObject workObj) {
this.workObj = workObj;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
workObj.methodA();
}
System.out.println("ThreadA 종료 ...");
}
}
/**
* WorkObject의 methodB()메서드만 호출하는 쓰레드
*/
class ThreadB extends Thread{
private WorkObject workObj;
public ThreadB(WorkObject workObj) {
this.workObj = workObj;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
workObj.methodB();
}
System.out.println("ThreadB 종료 ...");
}
}
package kr.or.ddit.basic;
public class T20_WaitNotifyTest {
public static void main(String[] args) {
DataBox dataBox = new DataBox();
ProducerThread pth = new ProducerThread(dataBox);
ConsumerThread cth = new ConsumerThread(dataBox);
pth.start();
cth.start();
}
}
//데이터를 공통으로 사용하는 클래스
class DataBox{
private String data;
//data가 null일떄 data값을 반환하는 메서드
public synchronized String getData() {
if(data == null) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String returnData = data;
System.out.println("읽어올데이터 : "+returnData);
data = null;
System.out.println(Thread.currentThread().getName()+"notify()호출");
notify();
return returnData;
}
//data 가 null일 경우에만 자료를 셋팅하는 메서드
public synchronized void setData(String data) {
if(this.data!=null) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.data=data;
System.out.println("셋팅한 데이터 "+this.data);
System.out.println(Thread.currentThread().getName()+"notify()호출");
notify();
}
}
//데이터를 셋팅만 하는 쓰레드
class ProducerThread extends Thread{
private DataBox dataBox;
public ProducerThread(DataBox dataBox) {
super("ProducerThread");
this.dataBox = dataBox;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
String data = "Data-" +i;
System.out.println("dataBox.serData("+data+")호출");
dataBox.setData(data);
}
}
}
//데이터를 읽어만 오는 쓰레드
class ConsumerThread extends Thread {
private DataBox dataBox;
public ConsumerThread(DataBox dataBox) {
super("ConsumerThread");
this.dataBox = dataBox;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
String data = dataBox.getData();
System.out.println("dataBox.getData() : "+data);
}
}
}
'고급 JAVA' 카테고리의 다른 글
JAVA -입출력 -비트 스트림 (0) | 2020.09.28 |
---|---|
JAVA -IO -File (0) | 2020.09.24 |
JAVA - 쓰레드 -syncCollection (0) | 2020.09.23 |
JAVA - 쓰레드 예제 - 은행 입출금 - Lock (0) | 2020.09.23 |
JAVA - 쓰레드 예제 - 은행 입출금 -synchronized (0) | 2020.09.23 |