본문

동기화(wait, notify, notifyAll)

반응형

쓰레드 동기화(wait, notify, notifyAll)

- 동기화의 효율을 높이기 위해 wait(), notify()를 사용. 

- Object클래스에 정의되어 있으며, 동기화 블록 내에서만 사용할 수 있다. 


# wait()

객체의 lock을 풀고 해당 객체의 쓰레드를 waiting pool에 넣는다.


# notify()

waiting pool에서 대기중인 쓰레드 중의 하나를 깨운다.


# notifyAll()

waiting pool에서 대기중인 모든 쓰레드를 깨운다.


sample) notify() 의해서 깨워진 쓰레드는 다시 withdraw() while 조건식을 확인해서 잔고가 부족하면 다시 wait() 호출하게 된다.


다음은 전에 동기화 예제에서 사용한 Account클래스에 wait() notify() 적용한 것이다.

source) SynchronizedEx05.java

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
package synchronizedEx;
 
public class SynchronizedEx05 {
 
    public static void main(String[] args) {
        Runnable runnable = new RunnableTest2();
        Thread thread01 = new Thread(runnable);
        Thread thread02 = new Thread(runnable);
 
        thread01.start();
        thread02.start();
    }
}
 
class Account_2 {
    int balance = 1000;
 
    /*
     * 출금을 위해 withdraw()가 호출되었을 때 잔고가 부족하면 wait()을 호출해서 쓰레드가 객체의 lock을 풀고 그 객체의
     * waiting pool에 들어가면서 제어권을 다른 쓰레드에게 양보하게 된다.
     */
    public synchronized void withdraw(int money) {
        /*
         * 여기서 if문 대신 while문을 사용한 이유는, 여러 쓰레드가 Account객체를 공유하기 때문에 다시 깨어났을 때도 다시
         * 한 번 조건을 확인해야하기 때문이다.
         */
        while (balance < money) {
            try {
                wait();
            } catch (Exception e) {
            }
        }
        balance -= money;
    }
 
    /*
     * 다른 쓰레드에 의해서 deposit()메서드가 호출되어 잔고가 증가하면서 notify()를 호출하면 객체의 wating pool에서
     * 기다리고 있던 쓰레드를 깨우게 된다.
     */
    public synchronized void deposit(int money) {
        balance += money;
        notify();
    }
}
 
class RunnableTest2 implements Runnable {
    Account_2 account = new Account_2();
 
    public void run() {
        while (account.balance > 0) {
            int money = (int) (Math.random() * 3 + 1* 100;
            account.withdraw(money);
            System.out.println("balance : " + account.balance);
        }
        account.deposit(1000);
    }
}
cs

 

result)

1
2
3
4
5
6
7
8
9
10
11
balance : 800
balance : 700
balance : 500
balance : 200
balance : 100
balance : 800
balance : 0
balance : 800
balance : 700
balance : 400
balance : 200
cs

 



- 출처 및 참고자료 : JAVA의정석(남궁성 저)


반응형

공유

댓글