๋ฉํฐ ์ฝ์ด ํ๋ก์ธ์์์๋ ์ฝ์ด๋ง๋ค ๋ณ๋์ ์บ์๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
์ฝ์ด๋ ๋ฉ๋ชจ๋ฆฌ์์ ์ฝ์ด์จ ๊ฐ์ ์บ์์ ์ ์ฅํ๊ณ ์บ์์์ ๊ฐ์ ์ฝ์ด์ ์์ ํฉ๋๋ค. ๋ค์ ๊ฐ์ ์ฝ์ด์ฌ ๋๋ ๋จผ์ ์บ์์ ์๋์ง ํ์ธํ๊ณ ์์ ๋๋ง ๋ฉ๋ชจ๋ฆฌ์์ ์ฝ์ด์ต๋๋ค.
๊ทธ๋ฌ๋ค๋ณด๋ ๋ฉ๋ชจ๋ฆฌ์ ํน์ ๋ณ์์ ๊ฐ์ด ๋ณ๊ฒฝ๋์๋๋ฐ ์บ์์๋ ๋ณ๊ฒฝ๋ ๊ฐ์ด ๋ฐ์๋์ง ์์ ๋ฉ๋ชจ๋ฆฌ์ ๊ฐ๊ณผ ์บ์์ ๊ฐ์ด ๋ค๋ฅธ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.
์์ฒญ๋๊ฒ ๊ฐ๋จํ ์ค๋ช ํ ๊ฒ์ด์ง๋ง ์ด๋ฌํ ์ํฉ์์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
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์ ์ฐ๋ฉด ์ฑ๋ฅ์์ผ๋ก ์ ํ๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ์บ์๊ฐ์ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ ๋ณด์ง ์์ผ๋ฉด ๊ตณ์ด 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 ํค์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
JVM์ ๋ฐ์ดํฐ๋ฅผ 4byte(32bit)๋จ์๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ int์ int๋ณด๋ค ์์ ํ์ ๋ค์ ํ ๋ฒ์ ์ฝ๊ฑฐ๋ ์ฐ๋ ๊ฒ์ด ๊ฐ๋ฅํฉ๋๋ค. ์ฆ, ํ๋์ ๋ช ๋ น์ด๋ก ์ฝ๊ฑฐ๋ ์ฐ๊ธฐ๊ฐ ๊ฐ๋ฅํ๋ค๋ ๋ป์ ๋๋ค. ํ๋์ ๋ช ๋ น์ด๋ ๋ ์ด์ ๋๋ ์ ์๋ ์ต์์ ์์ ๋จ์์ด๋ฏ๋ก, ์์ ์ ์ค๊ฐ์ ๋ค๋ฅธ ์ฐ๋ ๋๊ฐ ๋ผ์ด๋ค ํ์ด ์์ต๋๋ค.
๊ทธ๋ฌ๋, ํฌ๊ธฐ๊ฐ 8๋ฐ์ดํธ์ธ long๊ณผ double ํ์ ์ ๋ณ์๋ ํ๋์ ๋ช ๋ น์ด๋ก ๊ฐ์ ์ฝ๊ฑฐ๋ ์ธ ์ ์๊ธฐ ๋๋ฌธ์, ๋ณ์์ ๊ฐ์ ์ฝ๋ ๊ณผ์ ์์ ๋ค๋ฅธ ์ฐ๋ ๋๊ฐ ๋ผ์ด๋ค ์ฌ์ง๊ฐ ์์ต๋๋ค.
์ด๋ด ๋ ๋ค๋ฅธ ์ฐ๋ ๋๊ฐ ๋ผ์ด๋ค์ง ๋ชปํ๊ฒ ํ๋ ค๊ณ ์ง๊ธ๊น์ง ๊ณต๋ถํ๋ synchronized ๋ธ๋ก
์ ์ฌ์ฉํ ์ ์์ง๋ง, ์ง๊ธ ์ ๋ฆฌํ๊ณ ์๋ volatile
ํค์๋๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ ์์ต๋๋ค.
volatile long sharedVal; // long ํ์
์ ๋ณ์(8 byte)๋ฅผ ์์ํ
volatile double sharedVal; // double ํ์
์ ๋ณ์(8 byte)๋ฅผ ์์ํ
์ด๋ ๊ฒ volatile
์ ์ฌ์ฉํ ๋ณ์๋ ์ฝ๊ฑฐ๋ ์ฐ๊ธฐ์ ์์ํ
๋ฉ๋๋ค. ์์ํ๋ ์์
์ ๋ ์ด์ ๋๋ ์ ์๋ค๋ ์๋ฏธ์
๋๋ค.