Skip to content

Latest commit

ย 

History

History
129 lines (92 loc) ยท 5.12 KB

volatile๋ž€?.md

File metadata and controls

129 lines (92 loc) ยท 5.12 KB

volatile๋ž€?

๋ฉ€ํ‹ฐ ์ฝ”์–ด ํ”„๋กœ์„ธ์„œ์—์„œ๋Š” ์ฝ”์–ด๋งˆ๋‹ค ๋ณ„๋„์˜ ์บ์‹œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

cached

์ฝ”์–ด๋Š” ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ฝ์–ด์˜จ ๊ฐ’์„ ์บ์‹œ์— ์ €์žฅํ•˜๊ณ  ์บ์‹œ์—์„œ ๊ฐ’์„ ์ฝ์–ด์„œ ์ž‘์—…ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์‹œ ๊ฐ’์„ ์ฝ์–ด์˜ฌ ๋•Œ๋Š” ๋จผ์ € ์บ์‹œ์— ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์—†์„ ๋•Œ๋งŒ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ฝ์–ด์˜ต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‹ค๋ณด๋‹ˆ ๋ฉ”๋ชจ๋ฆฌ์˜ ํŠน์ • ๋ณ€์ˆ˜์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”๋ฐ ์บ์‹œ์—๋Š” ๋ณ€๊ฒฝ๋œ ๊ฐ’์ด ๋ฐ˜์˜๋˜์ง€ ์•Š์•„ ๋ฉ”๋ชจ๋ฆฌ์˜ ๊ฐ’๊ณผ ์บ์‹œ์˜ ๊ฐ’์ด ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์—„์ฒญ๋‚˜๊ฒŒ ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•œ ๊ฒƒ์ด์ง€๋งŒ ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์—์„œ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • volatile์„ ์‚ฌ์šฉํ•˜๊ธฐ : ๊ทธ๋Ÿฌ๋ฉด ์ฝ”์–ด๊ฐ€ ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ์ฝ์–ด์˜ฌ ๋•Œ ์บ์‹œ๊ฐ€ ์•„๋‹Œ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๊ฐ’์„ ์ฝ์–ด์˜ค๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค.
  • synchronized ๋ธ”๋ก ์‚ฌ์šฉํ•˜๊ธฐ : ์“ฐ๋ ˆ๋“œ๊ฐ€ synchronized ๋ธ”๋ก์œผ๋กœ ๋“ค์–ด๊ฐˆ ๋•Œ์™€ ๋‚˜์˜ฌ ๋•Œ, ์บ์‹œ์™€ ๋ฉ”๋ชจ๋ฆฌ๊ฐ„์˜ ๋™๊ธฐํ™”๊ฐ€ ์ด๋ฃจ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์˜ ๋ถˆ์ผ์น˜๊ฐ€ ํ•ด์†Œ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์˜ˆ์ œ ์ฝ”๋“œ

public class VolatileSample extends Thread {
    private double instanceVariable = 0;

    public void setDouble(double value) {
        this.instanceVariable = value;
    }

    @Override
    public void run() {
        while (instanceVariable == 0) {
            System.out.println(instanceVariable);
        }
    }
}
public class RunVolatile {
    public static void main(String[] args) {
        RunVolatile sample = new RunVolatile();
        sample.runVolatileSample();
    }

    public void runVolatileSample() {
        VolatileSample sample = new VolatileSample();
        sample.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Sleep ended !!!");
        sample.setDouble(-1);
        System.out.println("Set value is completed !!!");
    }
}

์ฝ”๋“œ์˜ ์˜ˆ์ƒ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • sample์ด๋ผ๋Š” VolatileSample ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์“ฐ๋ ˆ๋“œ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  • Thread.sleep() ๋ฉ”์†Œ๋“œ๋กœ 1์ดˆ ๋Œ€๊ธฐ ํ›„ instanceVariable ๊ฐ’์„ -1๋กœ ๋ณ€๊ฒฝํ•˜๊ณ  ๋๋ƒ…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์‹ค์ œ ๊ฒฐ๊ณผ๋Š” ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

๊ฐ’์ด -1๋กœ ๋ฐ”๋€Œ์ง€ ์•Š๊ณ  ๋ฌดํ•œ๋ฃจํ”„๊ฐ€ ๋๋‚˜์ง€ ์•Š๋Š” ๊ฒฐ๊ณผ ๋‚˜์˜ต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ๊ฐ€ ์ด๋ ‡๊ฒŒ ๋‚˜์˜ค๋Š” ์ด์œ ๊ฐ€ ๋ฌด์—‡์ผ๊นŒ์š”?

๋งจ ์œ„์˜ ๊ทธ๋ฆผ์„ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด CPU๋Š” ๊ฐ์ž์˜ ์บ์‹œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์œ„์™€ ๊ฐ™์ด ๋ฐ˜๋ณต์ ์œผ๋กœ ์ฐธ์กฐํ•˜๊ฒŒ ๋  ๋•Œ๋Š” ์บ์‹œ์— ๋„ฃ์–ด๋†“๊ณ  ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ฐธ์กฐํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ main ์“ฐ๋ ˆ๋“œ์—์„œ -1๋กœ ๋ฐ”๊ฟจ๊ธฐ ๋•Œ๋ฌธ์— VolatileSample ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์บ์‹œ๋Š” ๋ฐ”๋€Œ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ while ๋ฌธ์ด ๋๋‚˜์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

private volatile double instanceVariable = 0;

์ด ๋•Œ volatile ํ‚ค์›Œ๋“œ๋ฅผ ์„ ์–ธํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. volatile์„ ์“ฐ๋ฉด ์บ์‹œ๊ฐ€ ์•„๋‹Œ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๊ฐ’์„ ์ฝ์–ด์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


ํ•˜์ง€๋งŒ ํ•ญ์ƒ volatile์„ ์“ฐ๋ฉด ์•ˆ๋ฉ๋‹ˆ๋‹ค.

volatile์„ ์“ฐ๋ฉด ์„ฑ๋Šฅ์ƒ์œผ๋กœ ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์บ์‹œ๊ฐ„์˜ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์ง€ ์•Š์œผ๋ฉด ๊ตณ์ด volatiole์„ ์“ธ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

public class VolatileSample extends Thread {
    private double instanceVariable = 0;

    public void setDouble(double value) {
        this.instanceVariable = value;
    }

    @Override
    public void run() {
        try {
            while (instanceVariable == 0) {
                Thread.sleep(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

๊ทธ๋ž˜์„œ run() ๋ฉ”์†Œ๋“œ์—์„œ 1๋ฐ€๋ฆฌ์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ํ–ˆ๋”๋‹ˆ volatile ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ์ฝ”๋“œ๊ฐ€ ์ž˜ ๋๋‚˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ๊ฐ€ ๋ฌธ์ œ๊ฐ€ ์žˆ์„ ๋•Œ๋งŒ volatile ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.


volatile๋กœ long๊ณผ double์„ ์›์žํ™”ํ•˜๊ธฐ

JVM์€ ๋ฐ์ดํ„ฐ๋ฅผ 4byte(32bit)๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— int์™€ int๋ณด๋‹ค ์ž‘์€ ํƒ€์ž…๋“ค์€ ํ•œ ๋ฒˆ์— ์ฝ๊ฑฐ๋‚˜ ์“ฐ๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํ•˜๋‚˜์˜ ๋ช…๋ น์–ด๋กœ ์ฝ๊ฑฐ๋‚˜ ์“ฐ๊ธฐ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ๋ช…๋ น์–ด๋Š” ๋” ์ด์ƒ ๋‚˜๋ˆŒ ์ˆ˜ ์—†๋Š” ์ตœ์†Œ์˜ ์ž‘์—…๋‹จ์œ„์ด๋ฏ€๋กœ, ์ž‘์—…์˜ ์ค‘๊ฐ„์— ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋ผ์–ด๋“ค ํ‹ˆ์ด ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜, ํฌ๊ธฐ๊ฐ€ 8๋ฐ”์ดํŠธ์ธ long๊ณผ double ํƒ€์ž…์˜ ๋ณ€์ˆ˜๋Š” ํ•˜๋‚˜์˜ ๋ช…๋ น์–ด๋กœ ๊ฐ’์„ ์ฝ๊ฑฐ๋‚˜ ์“ธ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ์ฝ๋Š” ๊ณผ์ •์—์„œ ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋ผ์–ด๋“ค ์—ฌ์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿด ๋•Œ ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋ผ์–ด๋“ค์ง€ ๋ชปํ•˜๊ฒŒ ํ•˜๋ ค๊ณ  ์ง€๊ธˆ๊นŒ์ง€ ๊ณต๋ถ€ํ–ˆ๋˜ synchronized ๋ธ”๋ก์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ง€๊ธˆ ์ •๋ฆฌํ•˜๊ณ  ์žˆ๋Š” volatile ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

volatile long sharedVal;     // long ํƒ€์ž…์˜ ๋ณ€์ˆ˜(8 byte)๋ฅผ ์›์žํ™”
volatile double sharedVal;   // double ํƒ€์ž…์˜ ๋ณ€์ˆ˜(8 byte)๋ฅผ ์›์žํ™”

์ด๋ ‡๊ฒŒ volatile์„ ์‚ฌ์šฉํ•œ ๋ณ€์ˆ˜๋Š” ์ฝ๊ฑฐ๋‚˜ ์“ฐ๊ธฐ์— ์›์žํ™” ๋ฉ๋‹ˆ๋‹ค. ์›์žํ™”๋ž€ ์ž‘์—…์„ ๋” ์ด์ƒ ๋‚˜๋ˆŒ ์ˆ˜ ์—†๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.