Notice
Recent Posts
Recent Comments
«   2024/09   »
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
Archives
Today
Total
관리 메뉴

충분히 쌓여가는

쓰레드의 동기화(synchronization) 본문

Java/JAVA3

쓰레드의 동기화(synchronization)

빌드이너프 2023. 8. 7. 23:16

쓰레드의 동기화

멀티 쓰레드 프로세스에서는 다른 쓰레드의 작업에 영향을 미칠 수 있다

진행 중인 작업이 다른 쓰레드에게 간섭받지 않게 하려면 '동기화'가 필요

쓰레드의 동기화 - 한 쓰레드가 진행 중인 작업을 다른 쓰레드가 간섭하지 못하게 막는 것

동기화하려면 간섭받지 않아야 하는 문장들을 '임계 영역'으로 설정

임계영역은 lock 얻은 단 하나의 쓰레드만 출입가능(객체 1개에 lock 1개)

 

synchronized를 이용한 동기화

synchronized로 임계영역(lock이 걸리는 영역)을 설정하는 방법 2가지

한 번에 1개의 쓰레드만 임계 영역에 들어갈 수 있기 때문에 최소화하는 것이 좋다

 

동기화 되기 전의 코드

음수로 출력됨

class synchronizationTest {
    public static void main(String args[]) {
        Runnable r = new RunnableEx1();
        new Thread(r).start(); // ThreadGroup에 의해 참조되므로 gc대상이 아니다.
        new Thread(r).start(); // ThreadGroup에 의해 참조되므로 gc대상이 아니다.
    }
}

class Account {
    private int balance = 1000; // private로 해야 동기화의 의미가 있음

    public int getBalance() {
        return balance;
    }

    public void withdraw(int money) { // synchronized로 메서드를 동기화
        if(balance >= money) {
            try { Thread.sleep(1000);} catch(InterruptedException e) {}
            balance -= money;
        }
    } // withdraw
}

class RunnableEx1 implements Runnable {
    Account acc = new Account();

    public void run() {
        while(acc.getBalance() > 0) {
            // 100, 200, 300중의 한 값을 임으로 선택해서 출금(withdraw)
            int money = (int)(Math.random() * 3 + 1) * 100;
            acc.withdraw(money);
            System.out.println("balance:"+acc.getBalance());
        }
    } // run()
}


balance:700
balance:700
balance:400
balance:300
balance:200
balance:0
balance:-100

 

동기화 된 후의 코드

음수가 나올 수가 없음

class synchronizationTest {
    public static void main(String args[]) {
        Runnable r = new RunnableEx1();
        new Thread(r).start(); // ThreadGroup에 의해 참조되므로 gc대상이 아니다.
        new Thread(r).start(); // ThreadGroup에 의해 참조되므로 gc대상이 아니다.
    }
}

class Account {
    private int balance = 1000; // private로 해야 동기화의 의미가 있음

    public synchronized int getBalance() { // 읽을 때도 동기화(synchronized) 해주기
        return balance;
    }

    public synchronized void withdraw(int money) { // synchronized로 메서드를 동기화
        if(balance >= money) {
            try { Thread.sleep(1000);} catch(InterruptedException e) {}
            balance -= money;
        }
    } // withdraw
}

class RunnableEx1 implements Runnable {
    Account acc = new Account();

    public void run() {
        while(acc.getBalance() > 0) {
            // 100, 200, 300중의 한 값을 임으로 선택해서 출금(withdraw)
            int money = (int)(Math.random() * 3 + 1) * 100;
            acc.withdraw(money);
            System.out.println("balance:"+acc.getBalance());
        }
    } // run()
}


balance:900
balance:800
balance:700
balance:600
balance:300
balance:100
balance:100
balance:0
balance:0

'Java > JAVA3' 카테고리의 다른 글

람다식(Lambda Expression)  (0) 2023.08.09
wait()와 notify()  (0) 2023.08.08
join(), yield()  (0) 2023.08.07
suspend(), resume(), stop()  (0) 2023.08.07
sleep(), interrupt()  (0) 2023.08.04