volatile

image
  • 기본적인 λ©€ν‹° ν”„λ‘œμ„ΈμŠ€μ˜ ꡬ쑰.

  • Core(CPU) λ³„λ‘œ, μΊμ‹œλ“€μ„ κ°€μ§€κ³  있고, L3 λ₯Ό 거쳐 RAM으둜 κ°€λŠ” ꡬ쑰.

  • λ§Œμ•½μ— L1 cacheμ—μ„œ A λ©”λͺ¨λ¦¬μ˜ 값에 μ—…λ°μ΄νŠΈκ°€ μΌμ–΄λ‚˜λ©΄ μ–΄λ–»κ²Œ 될까?

    • κ·Έ μ—…λ°μ΄νŠΈκ°€ RAM에 μ „νŒŒλ λ•Œ κΉŒμ§€λŠ” λ‹€λ₯Έ μ½”μ–΄μ—μ„œλŠ” μ•Œ 수 μ—†μŒ. (μ—…λ°μ΄νŠΈκ°€ μ•ˆλ˜μ—ˆμœΌλ‹ˆ)

    • data inconsistency

  • 이 ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄, ν•΄λ‹Ή λ³€μˆ˜μ˜ λ³€ν™”κ°€ main memoryκΉŒμ§€ λ°”λ‘œ μ „νŒŒλ¨μ„ 의미. ([[compare-and-swap]] λΌλŠ” 방법을 μ΄μš©ν•΄μ„œ)

Memory Visibility

public class TaskRunner {

    private static int number;
    private static boolean ready;

    private static class Reader extends Thread {

        @Override
        public void run() {
            while (!ready) {
                Thread.yield();
            }

            System.out.println(number);
        }
    }

    public static void main(String[] args) {
        new Reader().start();
        number = 42;
        ready = true;
    }
}
  • μŠ€λ ˆλ“œλŠ” 2개 main, runner thread

  • main threadμ—μ„œ μ—…λ°μ΄νŠΈ ν•œ λ³€μˆ˜ (number, ready) κ°€ runner thread μ—κ²Œλ„ λ°”λ‘œ 읽을 수 μžˆμ„κΉŒ?

    • 그럴 μˆ˜λ„, μ‹œκ°„μ΄ 걸릴 μˆ˜λ„, ν˜Ήμ€ μ—…λ°μ΄νŠΈκ°€ μ•ˆλ  μˆ˜λ„ 있음.

    • μ™œ?

    • processors tend to queue those writes in a special write buffer

    • λ°”λ‘œ μ μš©λ˜λŠ” 것이 μ•„λ‹Œ, write buffer에 queue λ₯Ό λ˜μ Έμ„œ, 일정 μ‹œκ°„μ΄ μ§€λ‚œ 후에 main memory에 반영되기 λ•Œλ¬Έ

  • 즉 μ •λ¦¬ν•˜μžλ©΄,

    • main threadκ°€ number, ready λ³€μˆ˜λ₯Ό μ—…λ°μ΄νŠΈ ν–ˆμ„ λ•Œ, reader threadκ°€ μ—…λ°μ΄νŠΈ 된 λ³€μˆ˜λ₯Ό μ½λŠ” λ‹€λŠ” 보μž₯이 μ—†μŒ.

    • 심지어 programe order (number -> ready) 순으둜 μ—…λ°μ΄νŠΈν•΄μ„œ 보기 λ³΄λ‹€λŠ” μ•„μ˜ˆ λ‹€λ₯Έ μˆœμ„œ (ready -> number) μˆœμœΌλ‘œλ„ λ³Ό 수 있음. (개발자의 μ˜λ„μ™€λŠ” μ•„μ˜ˆ λ‹€λ₯΄κ²Œ..)

    • ready = true둜 λ°”λ€Œμ—ˆμ§€λ§Œ numberλŠ” μ—…λ°μ΄νŠΈ λ˜μ§€ μ•Šμ€ 채 0을 ν”„λ¦°νŠΈ ν•˜κ³  μ’…λ£Œλ  μˆ˜λ„ μžˆλ‹€λŠ” λœ»μΈλ“―.

To ensure programm order

  • To ensure that updates to variables propagate predictably to other thread

  • ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•œ μˆœμ„œλŒ€λ‘œ λ³€μˆ˜λ“€μ΄ μ—…λ°μ΄νŠΈ λ˜λŠ” 것을 보μž₯ν•˜κΈ° μœ„ν•΄μ„ ?

  • volatile λ³€μˆ˜λ₯Ό μ‚¬μš©.

public class TaskRunner {

    private volatile static int number;
    private volatile static boolean ready;

    // same as before
}
  • μ΄λ ‡κ²Œ ν•˜λ©΄.. number μ—…λ°μ΄νŠΈ 후에 readyκ°€ μ—…λ°μ΄νŠΈ λœλ‹€.

  • 42 print ν›„ μ’…λ£Œλ₯Ό μ˜ˆμΈ‘ν•  수 μžˆμ„λ“―.

For multithreaded applications

  • 일관적인 행동을 μœ„ν•΄μ„  2κ°€μ§€ 룰을 μ§€μΌœμ•Όν•¨.

    1. Mutual Exclusion : 치λͺ…적인 λΆ€λΆ„μ—λŠ” ν•œλ²ˆμ— ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œλ§Œ μ‹€ν–‰ν•˜λ„λ‘.

    2. Visibility : 곡유된 μžμ›μ— ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œλ‘œ λΆ€ν„° λ§Œλ“€μ–΄μ§„ 변화듀은, λ‹€λ₯Έ μŠ€λ ˆλ“œλ“€μ΄ λ³Ό 수 μžˆμ–΄μ•Όν•¨. μ™œ? data consistency λ₯Ό μœ μ§€ν•˜κΈ° μœ„ν•΄

  • [[sy]] λ©”μ„œλ“œλŠ” 1,2 번의 룰을 λͺ¨λ‘ 만쑱 μ‹œν‚¬ 수 있음.

    • λ‹€λ§Œ μƒλ‹Ήν•œ μžμ›μ„ μ†Œλͺ¨.

  • κ·Έλ ‡μ§€λ§Œ [[volatile]] λŠ” mutual exclusion 없이 2번 visibility 츑면을 λ§Œμ‘±μ‹œν‚΄.

μ°Έκ³ 

Last updated

Was this helpful?