Skip to content

Latest commit

Β 

History

History
110 lines (73 loc) Β· 4.42 KB

2021-10-10-ν† .md

File metadata and controls

110 lines (73 loc) Β· 4.42 KB

Java의 Atomic λ³€μˆ˜

κ³΅μœ λ˜λŠ” 변동 κ°€λŠ₯ν•œ μƒνƒœλŠ” λ™μ‹œμ„±μ΄ κ°œμž…λ  λ•Œ 문제λ₯Ό μ΄ˆλž˜ν•  수 μžˆλ‹€. λ³€κ²½ κ°€λŠ₯ν•œ 곡유 κ°œμ²΄μ— λŒ€ν•œ μ—‘μ„ΈμŠ€κ°€ μ œλŒ€λ‘œ κ΄€λ¦¬λ˜μ§€ μ•ŠμœΌλ©΄ μ‘μš© ν”„λ‘œκ·Έλž¨μ—μ„œ λ™μ‹œμ„± 였λ₯˜κ°€ λ°œμƒν•  수 μžˆλ‹€. μ˜€λŠ˜μ€ λ™μ‹œμ„± λ¬Έμ œμ™€ λ™μ‹œ μ—‘μ„ΈμŠ€λ₯Ό μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ Atomic λ³€μˆ˜λ₯Ό 곡뢀해보겠닀.

λ™μ‹œμ„± 문제

ν˜„μ‹€ μ„Έκ³„μ˜ 일을 λ™μ‹œμ„± λ¬Έμ œμ— λΉ—λŒ€μ–΄ ν‘œν˜„ν•΄λ³΄μž. 톡μž₯이 ν•˜λ‚˜ 있고 두 μ‚¬λžŒμ΄ 1000원씩 μž…κΈˆμ„ ν•œλ‹€κ³  κ°€μ •ν•΄λ³΄μž.


톡μž₯μ—λŠ” 1000원이 이미 λ“€μ–΄μžˆμ—ˆκ³  μ‚¬λžŒ 2λͺ…이 각각 1000원씩 μž…κΈˆμ„ ν–ˆλ‹€. λ‹Ήμ—°νžˆ 톡μž₯의 μž”μ•‘μ€ 3000원이 λœλ‹€κ³  μƒκ°λœλ‹€. ν•˜μ§€λ§Œ κ·Έλ ‡μ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€.


사싀 λ”ν•˜κΈ° 연산은 μ»΄ν“¨ν„°μ—μ„œ λ‚΄λΆ€μ μœΌλ‘œ 값을 읽고 μ¦κ°€μ‹œν‚€κ³  λ‹€μ‹œ μ—…λ°μ΄νŠΈμ˜ 과정이닀. 순차적으둜 μ‚¬λžŒ1이 1000원을 μž…κΈˆν•˜κ³  λ‹€μŒμ— μ‚¬λžŒ2κ°€ μž…κΈˆμ„ ν•˜λ©΄ κΈ°λŒ€ν•œλŒ€λ‘œ 3000원이 μ €μž₯될 것이닀. 그런데 μ‚¬λžŒ1κ³Ό μ‚¬λžŒ2κ°€ λ™μ‹œμ— 톡μž₯에 μ ‘κ·Όν•  μˆ˜λ„ μžˆλ‹€. κ·Έλ ‡κ²Œ 되면 λ‘˜λ‹€ κΈ°μ‘΄ μž”μ•‘μΈ 1000원을 읽을 것이고 두 μ‚¬λžŒ λͺ¨λ‘ 톡μž₯에 2000원을 μ“°κ²Œ λ˜μ–΄ 잘λͺ»λœ κΈˆμ•‘μ΄ 톡μž₯에 λ“€μ–΄κ°€λŠ” 것이닀.


μΆœκΈˆμ„ ν•  λ•Œλ„ λ§ˆμ°¬κ°€μ§€λ‹€. 톡μž₯에 1000원이 μžˆλŠ”λ° μ‚¬λžŒ1이 1000μ›” μΆœκ·Όν•˜λ©΄ 톡μž₯에 남은 μž”μ•‘μ€ 0원이 λœλ‹€. κ·Έ λ‹€μŒ μ‚¬λžŒ2κ°€ 1000원을 μΆœκΈˆν•˜λ €κ³  ν•˜λ©΄ 톡μž₯에 더이상 남은 μž”μ•‘μ΄ μ—†κΈ° λ•Œλ¬Έμ— μΆœκΈˆμ„ ν•  수 μ—†λ‹€. 그런데 두 μ‚¬λžŒμ΄ λ™μ‹œμ— 톡μž₯에 μ ‘κ·Όν•œλ‹€λ©΄ 두 μ‚¬λžŒ λͺ¨λ‘ 남은 μž”μ•‘μ΄ 1000원인 것을 ν™•μΈν•˜κ³  각자 1000원을 μΆœκΈˆμ„ ν•  수 μžˆλŠ” 잘λͺ»λœ 상황이 μΌμ–΄λ‚˜κ²Œ λœλ‹€.


μ½”λ“œλ‘œ κ΅¬ν˜„μ„ ν•΄λ³΄μ•˜λ‹€. Bank ν΄λž˜μŠ€μ—λŠ” μž”μ•‘μ„ ν‘œμ‹œν•˜λŠ” balance λ³€μˆ˜κ°€ μžˆλ‹€. 그리고 increment λ©”μ†Œλ“œλŠ” 톡μž₯의 κΈ°μ‘΄ μž”μ•‘μ— 1000원을 λ”ν•΄μ£ΌλŠ” μž…κΈˆ μ—­ν•  λ©”μ†Œλ“œμ΄λ‹€.
public class Bank {
    private int balance; // μž”μ•‘

    public int increment() {
        return  balance += 1000;
    }

    public int getBalance() {
        return balance;
    }
}

μŠ€λ ˆλ“œ 2개λ₯Ό μƒμ„±ν•˜κ³  각각 Bank의 increment λ©”μ†Œλ“œλ₯Ό 100번 μ‹€ν–‰ν•˜μ—¬ 1000원을 100번 μž…κΈˆν•˜λ„λ‘ ν…ŒμŠ€νŠΈν–ˆλ‹€. 1000원을 100번 μž…κΈˆν•˜λ©΄ 10λ§Œμ›μ΄κ³ , μŠ€λ ˆλ“œκ°€ 2κ°œκ°€ 각각 100번 μž…κΈˆν•˜λ―€λ‘œ 톡μž₯에 μŒ“μΈ μ΅œμ’… μž”μ•‘μ€ 20λ§Œμ›μœΌλ‘œ μ˜ˆμƒμ΄ 될 것이닀. κ·Έλƒ₯ for문만 돌리면 생각보닀 거의 μ˜¬λ°”λ₯Έ κ°’λ§Œ λ‚˜μ™€μ„œ Thread.sleep(100)을 쀑간에 λ„£μ–΄λ΄€λ‹€.
public class Test01 {

    public static void main(String[] args) throws InterruptedException {
        Bank bank = new Bank();
        int threadCount = 2;

        CountDownLatch latch = new CountDownLatch(threadCount);
        for (int i = 0; i < threadCount; i++) {
            
            new Thread(() -> {
                for (int j = 1; j <= 100; j++) {
                    System.out.println(Thread.currentThread().getName() + " " + bank.increment() +"원");

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                latch.countDown();

            }).start();
        }

        latch.await();
        System.out.println("total = " + bank.getBalance());
    }
}

κ²°κ³ΌλŠ” 맀번 λ‹¬λžμ§€λ§Œ 20λ§Œμ›κ³Ό μ˜€μ°¨κ°€ ν΄λ•ŒλŠ” μ•„λž˜μ™€ 같이 172000원이 λ‚˜μ˜€κΈ°λ„ ν–ˆλ‹€.

Thread-0 164000원

Thread-1 165000원

Thread-1 166000원

Thread-0 166000원

Thread-0 168000원

Thread-1 167000원

Thread-0 169000원

Thread-1 170000원

Thread-0 171000원

Thread-1 172000원

total = 172000

이와 같이 두 μŠ€λ ˆλ“œκ°€ 같은 값에 λ™μ‹œμ— μ ‘κ·Όν•˜λŠ” κ²½μš°κ°€ λ°œμƒν•œλ‹€.