728x90
반응형

wait()와 notify()

한 쓰레드가 객체에 lock을 걸고 어떤 조건이 만족될 때 까지 기다려야하는 경우, 이 쓰레드를 그대로 놔두면 이 객체를 사용하려는 다른 쓰레드들은  lock이 풀릴 때까지 같이 기다려야하는 상황이 발생합니다.

이러한 비효율을 개선하기 위해서 wait()와  notify()를 사용합니다. 한 쓰레드가 lock을 걸고 오래 기다리는 대신에 wait()를 호출하여 다른 쓰레드에게 제어권을 넘겨주고 대기상태로 기다리다가 다른 쓰레드에 의해서 notify()가 호출되면 다시 실행상태가 되도록하는 것을 말합니다.



wait()와 notify()의 특징
-  wait()와 notify()는 Thread클래스가 아닌 Object클래스에 정의댄 메서드이므로 모든 객체에서 호출이 가능합니다.
- 쓰레드가 wait()를 호출하면 그 때까지 자신이 객체에 걸어 놓았던 lock을 풀고, wait()가 호출된 객체의 대기실(waiting pool)에서 기다립니다.
- notify()는 waiting pool에 있는 쓰레드 중에 하나만 깨우고 notifyAll()모든 객체를 깨웁니다.
- notify()로 호출할 경우 어떤 객체가 깨어날지 모르기때문에 notifyAll()로 모든 객체를 깨운 뒤에 JVM의 쓰레드 스케쥴링에 의해서 처리되는 것이 안전합니다.
- 동기화 블럭(synchronized블록)내에서만 사용할 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// wait()와 notify() 예제
class Account{
    int balance = 1000;
 
    public synchronized void withdraw(int money){
        /* 잔고가 부족할 경우 wait()를 호출하여 lock을 풀고 waiting pool에
           들어가면서 제어권을다른 쓰레드에게 양보하게 됩니다. */
        while(balance < money){ 
            try{
                wait();
            }catch(InterruptedException e){ }
        }
 
        balance -= money;
    }
    
    /* 다른 쓰레드에 의해서 deposit()메서드가 호출되어 잔고가 증가하면서 notify()를 
       호출하면 객체의 waiting pool에서 기다리고 있던 쓰레드를 깨우게 됩니다. */
    public synchronized void deposit(int money){
        balance += money;
        notify();
    }
}
cs


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// wait()와 notify() 예제2
class ThreadEx{
    public static void main(String args[]){
        MyThreadEx th1 = new MyThreadEx("*");
        MyThreadEx th2 = new MyThreadEx("**");
        MyThreadEx th3 = new MyThreadEx("***");
        th1.start();
        th2.start();
        th3.start();
 
        try{
            Thread.sleep(2000);
            th1.suspend();
            Thread.sleep(2000);
            th2.suspend();
            Thread.sleep(3000);
            th1.resume();
            Thread.sleep(3000);
            th1.stop();
            th2.resume();
            th2.stop
            Thread.sleep(3000);
            th3.stop();
        }catch(InterruptedException e){ }
        }
    }
}
 
class MyThreadEx implements Runnable{
    static final int RUNNING = 0;
    static final int SUSPENDED = 1;
    static final int STOPPED = 2;
 
    private int state = RUNNING;
    Thread th;
 
    MyThreadEx(String name){
        th = new Thread(this, name); /// Thread(Runnable r, String name)
    }
 
    public void run(){
        String name = Thread.currentThread().getName();
        
        while(true){
            System.out.println(name);
            try{
                Thread.sleep(1000);
            }catch(InterruptException e){ }
            
           // state가 STOPPED이면 checkState가 true를 변환해서 while문을 벗어나게 됩니다.
           if(checkState()){
               break;
           }
        }
    }
 
    public synchronized void setState(int state){
        this.state = state;
        
        // state가 SUSPENDED였다가 RUNNING으로 변경되면, notify()를 호출합니다.
        if(state = RUNNING){
            notify();
        }else{
            th.interru
        }
    }
 
    public synchronized boolean checkState(){
        // state가 SUSPENDED면 wait를 호출해서 쓰레드를 대기상태로 만듬
        while(state==SUSPENDED){
            try{
                wait();
            }catch(InterruptedException e){ }
        }
        // state가 STOPPED이면 true를, 그 외는 false를 리턴합니다.
        return state == STOPPED;
    }
 
    public void suspend(){
        setState(SUSPENDED);
    }
    public void resume(){
        setState(RUNNING);
    }
    public void stop(){
        setState(STOPPED);
    }
    public void start(){
        th.start();
    }
}
cs



728x90
반응형

'JAVA > JAVA 스레드' 카테고리의 다른 글

[java] 쓰레드의 동기화  (0) 2017.11.02
[java] 쓰레드의 실행제어  (0) 2017.11.02
[java] 데몬 쓰레드  (0) 2017.11.01
[java] 쓰레드 그룹  (0) 2017.11.01
[java] 쓰레드의 우선순위  (0) 2017.11.01
[java] 싱글쓰레드와 멀티쓰레드  (0) 2017.11.01
[java] start()와 run()  (0) 2017.11.01
[java] 쓰레드 구현 및 실행  (0) 2017.11.01
블로그 이미지

nineDeveloper

안녕하세요 현직 개발자 입니다 ~ 빠르게 변화하는 세상에 뒤쳐지지 않도록 우리모두 열심히 공부합시다 ~! 개발공부는 넘나 재미있는 것~!

댓글을 달아 주세요