์ฐ๋ ๋ ๋๊ธฐํ (sync, volatile, AtomicClass)
by JiwonDev์ฐ๋ ๋์ ๋๊ธฐํ : ํ ์ฐ๋ ๋๊ฐ ์งํ์ค์ธ ์์ ์ ๋ค๋ฅธ ์ฐ๋ ๋๊ฐ ๊ฐ์ํ์ง ๋ชปํ๊ฒ ํ๋ ๊ฒ.
์ฐ๋ ๋๋ class์ ๋ฉค๋ฒ ๋ณ์(์์)์ ์ฌ์ฉํ๋ค. ๋ฉํฐ์ฐ๋ ๋ ํ๊ฒฝ์์๋ ์ฐ๋ ๋ ๋๊ธฐํ๋ฅผ ํ์ง์์ผ๋ฉด, ์ฌ๊ฐํ ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์๋ค.
#์๋ฐ์ synchronized ํค์๋
์๋ฐ๋ synchronized ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ํด๋น ๋ฉ์๋๋ฅผ ์๊ณ์์ญ์ผ๋ก ๋ง๋ค ์ ์๊ฒ ํด์ค๋ค. ์๊ณ์์ญ์์๋ ๋์์ ํ ์ฐ๋ ๋๋ง ์ ๊ทผํด์ ์ฌ์ฉํ ์ ์๋๋ก ๋ค๋ฅธ์ฐ๋ ๋์ ์ ๊ทผ์ ๋ง๋๋ค(lock)
- synchronized ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค.
- synchronized block์ ๋ง๋ค์ด ์ผ๋ถ๋ง ๋๊ธฐํ์ฒ๋ฆฌํ๋ค. (์ฑ๋ฅ ํฅ์์ ์ํจ)
public synchronized void method() {
// ์๊ณ์์ญ
}
public void function() {
synchronized(๊ฐ์ฒด์ ์ฐธ์กฐ๋ณ์) {
// ์๊ณ์์ญ
}
}
synchronzied๋ ๋ค์์ ์ฐ๋ ๋์๊ฒ ๊ณต์ ๋๋ ๊ฐ์ฒด ์ ๊ทผ์ ํต์ ํ๋ ์๋ฐ์ ์ฒซ๋ฒ์งธ ๋๊ธฐํ ๋ฉ์นด๋์ฆ์ด์๋ค. ํ์ง๋ง ์ด๊ฒ๋ง์ผ๋ก๋ ๋ค์ํ ์ํฉ์ ๋์ฒํ๊ธฐ ํ๋ค์๊ธฐ์ Java5 ์ Concurrent ๊ด๋ จ ํด๋์ค๋ค์ ์ถ๊ฐํ์๋ค.
# Atomic ํด๋์ค (java.concurrent.atomic)
ํค์๋ ๋ง๊ณ ๋ ์๋ฐ์์๋ CAS(compare and swap) ๋ฐฉ์์ผ๋ก ์ค๋ ๋ ์์ ์ฑ์ ๋ณด์ฅํ๋ Atomic ํจํค์ง๋ฅผ ์ ๊ณตํ๋ค.
import java.util.concurrent.atomic.AtomicInteger;
private AtomicInteger counter = new AtomicInteger();
public int getNextUniqueIndex() {
return counter.getAndIncrement();
}
CAS ๋ฐฉ์์ ์์ ์ด ์ฝ์๋ ๋ณ์์ ๊ฐ์ ๊ธฐ์ตํ๊ณ ์๋ค๊ฐ ๋ณ๊ฒฝ์ ์๋ฃํ๊ธฐ ์ง์ ์ ์ฝ์๋ ๋ณ์์ ๊ฐ์ด ๊ทธ๋๋ก์ธ์ง ํ์ธํ๊ณ ์๋๋ผ๋ฉด ์คํ์ ๋ฌด์ฐ์ํค๋ ๋ฐฉ์์ด๋ค.
// C์ธ์ด๋ก ๊ตฌํํ CAS
int compare_and_swap(int* reg, int oldval, int newval){
// ๋ณ๊ฒฝ์ ๊ฐ์ ์ ์ฅํด๋๋ค๊ฐ, ํธ์ง ์๋ฃ ํ์๋ ๋ฉ๋ชจ๋ฆฌ์ ๊ธฐ์กด ๊ฐ์ด ๋จ์์์ด์ผ swapํ๋ ๋ฐฉ์.
int old_reg_val = *reg;
if (old_reg_val == oldval){
*reg = newval;
}
return old_reg_val;
}
# volatile (๋ณผ๋ผํธ) ํค์๋
volatile ํค์๋๋ ์๋ฐ ๋ณ์๋ฅผ CPU ์บ์๊ฐ ์๋ '๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ'ํ ๊ฒ์ ๋ช ์ํด ๋ณ์์ ๊ฐ์์ฑ์ ๋ณด์ฅํ๋ค.
์ฆ volatile์ ๋ณ์์ ์ฝ๊ธฐ/์ฐ๊ธฐ ๋ช ๋ น์ ๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ๋ก๋ถํฐ ์ํํ๋ค๋ ๊ฒ์ ๋ณด์ฅํ๋ค. ์ด๋ ์ฝ๊ธฐ ์ค๋ ๋์ ์ฐ๊ธฐ ์ค๋ ๋๊ฐ ํจ๊ป ๋์ํ์ ๋ ์ผ์ด๋๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ด๋ค
@ ์ ์ฝ๊ธฐ / ์ฐ๊ธฐ๋ฅผ ๊ฐ์ดํ๋ฉด ๋ฌธ์ ๊ฐ ์๊ธฐ๋ ๊ฑธ๊น?
CPU์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ๋, ์ฑ๋ฅ์ ํฅ์์ํค๊ธฐ ์ํด Main Memory์์ ๊ณ์ ์ฝ๋ ๊ฒ์ด ์๋๋ผ ๊ฐ CPU ์ฝ์ด์ ์บ์์ ์ ์ฅํ์ฌ ์ฌ์ฉํ๋ค. ๊ทธ๋ ๋ค๋ฉด ๋ฉํฐ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ ์ฑ์์, CPU ์ฝ์ด๊ฐ ์ฌ๋ฌ๊ฐ๋ผ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
์ด๋ ๊ฒ ์ผ๋ฐ ๋ณ์(non-volatile)์ ๋ํ ์์ ์ JVM์ด ๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ๋ก๋ถํฐ CPU ์บ์๋ฅผ ํตํด ๋ณ์๋ฅผ ์ฝ๊ฑฐ๋ ๋ฐ๋๋ก CPU ์บ์๋ก ๋ถํฐ ๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๊ฑฐ๋ ํ ๋ ์ด๋ ํ ๋๊ธฐํ ๋ณด์ฅ๋ ํด์ฃผ์ง ์๋๋ค.
์๋ฅผ ๋ค์ด ๋ ์ด์์ ์ฐ๋ ๋๊ฐ ๋ค์๊ณผ ๊ฐ์ ๊ณต์ ๊ฐ์ฒด๋ก ์ ๊ทผํ๋ ๊ฒฝ์ฐ๋ฅผ ์๊ฐํด๋ณด์.
// Thread-1 : counter ๋ณ์๋ฅผ ์์ ํจ. (+1์ฉ ์ฆ๊ฐ์ํด)
// Thread-2 : counter ๋ณ์๋ฅผ ์ฝ์
public class SharedObject {
public int counter = 0;
}
๋ง์ฝ volatile ํค์๋๋ฅผ ์ ์ธํ์ง ์๋๋ค๋ฉด, counter ๋ณ์๊ฐ ์ธ์ CPU ์บ์์์ ๋ฉ์ธ๋ฉ๋ชจ๋ฆฌ๋ก ์ด๋๋ ์ง ๋ณด์ฅํ ์ ์๋ค. ์ฆ ๋ฉํฐ์ฝ์ด CPU์ ๊ฒฝ์ฐ ๊ฐ์ ๋ณ์์์๋ ๋ค๋ฅธ ๊ฐ์ ๊ฐ์ง๊ณ ์์ ์ ์๋ค๋ ๋ง์ด๋ค. ์ด๋ ๊ฒ ์ฐ๋ ๋๊ฐ ๋ณ๊ฒฝํ ๊ฐ์ด ๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ์ ๋ฐ์๋์ง ์์ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ํด๋น ๊ฐ์ ๋ณผ ์ ์๋ ๋ฌธ์ ๋ฅผ '๊ฐ์์ฑ ๋ฌธ์ ' ๋ผ๊ณ ํ๋ค.
์ฌ๊ธฐ์์ ๋ค์๊ณผ ๊ฐ์ด volatile ํค์๋๋ฅผ ์ฌ์ฉํ๊ฒ๋๋ค๋ฉด ํด๋น ๋ณ์์ ๋ํ ์ฐ๊ธฐ ์์ ์ ์บ์์์ด ๋ฐ๋ก ๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ์ ์ด๋ฃจ์ด์ง๋ค. ์ฆ ๋ค๋ฅธ ์ฐ๋ ๋์ ์ฐ๊ธฐ ์์ ์ ๋ํ ๊ฐ์์ฑ์ ๋ณด์ฅํ๋ค.
@ JDK1.5 ์ดํ์ volatile
์ฐธ๊ณ ๋ก JDK1.5 ๋ถํฐ๋ volatile ํค์๋๋ ๋จ์ํ ๊ฐ์์ฑ์ ๋ณด์ฅํ๋ ๊ฒ๋ณด๋ค ๋ ๋ง์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ก ๋ฐ๋์๋ค.
https://parkcheolu.tistory.com/16
- volatile ๋ณ์๋ฅผ ์์ ํ ๋ ํ์ฌ๊น์ง ์์ ํ ๋ชจ๋ ๋ณ์๋ค์ด ๋ฉ์ธ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ(flushed)๋๋ค.
- volatile ๋ณ์๋ฅผ ์บ์๋ก ์ฝ์ด๋ค์ผ ๋ ์์์ ๊ฐ์ด ์ ์ฅํ ๋ณ์๋ค๋ ๊ฐ์ด ์ฝ๋๋ค.
@ ๊ทธ๋ผ volatile์ด ๋ฌด์กฐ๊ฑด ์ข์๊ฑด๊ฐ์?
volatile์ ํ ๋ณ์๋ฅผ ๋๊ณ ์ค์ง ํ ์ฐ๋ ๋๋ง ์ฝ๊ธฐ/์ฐ๊ธฐ ์์ ์ ํ๊ณ , ๋ค๋ฅธ ์ฐ๋ ๋๋ค์ ์ฝ๊ธฐ ์์ ๋ง ํ๋ค๋ฉด ์ฌ์ฉํ์ ๋ ๋ ผ๋ธ๋กํน ๋ฉํฐ์ฐ๋ ๋๋ฅผ ๊ตฌํํ ์ ์๋ค. ํ์ง๋ง ์ด ๊ฒฝ์ฐ๊ฐ ์๋๋ผ๋ฉด ๋ง์ด ๋ฌ๋ผ์ง๋ค.
volatile ์ ์ธ์ ๋ณ์์ ์ ๊ทผํ๋ ์ฐ๋ ๋๋ค์ ๋ธ๋ก์ํค์ง ์๋๋ค. ๊ทธ๋์ ๊ณต์ ๋ณ์๋ฅผ ์ฌ๋ฌ ์ฐ๋ ๋๊ฐ ๋์์ ์ฐ๋(write) ์๊ณ์์ญ์ ๋ํด์ ๋ช ๋ น์ด ๋ฌด์๋ ๊ฐ๋ฅ์ฑ์ด ์๋ค. ์ฆ ํด๋น ๋ช ๋ น์ ์์์ฑ์ ๋ณด์ฅ์ ๋ณด์ฅํ์ง ์๋๋ฐ, ์ด๋ฐ ๊ฒฝ์ฐ์๋ synchronized ํค์๋๊ฐ ํ์ํ๋ค. ๋ง์ฝ synchrozined ๋ก ๊ธฐ๋ฅ์ด ๋ถ์กฑํ๋ค๋ฉด ์์์ ์ธ๊ธํ java.util.concurrent์ ์๋ Atomic ํด๋์ค๋ค์ ์ฌ์ฉํ๋ฉด ๋๋ค.
๋ํ volatile ๋๋ฌธ์ CPU ์บ์๋ฅผ ์ฐ์ง ๋ชปํด์ ์ฑ๋ฅ์ด ๋จ์ด์ง ๊ฐ๋ฅ์ฑ์ด ์๊ณ , JVM์ ์ฝ๋ ์ฌ์ ๋ฆฌ, ์ต์ ํ๋ ํด๋น ํค์๋ ๋๋ฌธ์ ๋์ํ์ง ์์ ์ ์์์ ์ ์ํ์.
'๐๊ธฐ๋ณธ ์ง์ > Java ๊ธฐ๋ณธ์ง์' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
ํ๋ก๊ทธ๋๋ฐ ์ํฐํจํด (Anti-pattern) (0) | 2021.08.02 |
---|---|
StringBuffer์ StringBulider (0) | 2021.07.27 |
์๋ฐ์ String๊ณผ Constant Pool (2) | 2021.07.27 |
.equals์ .hashCode()๋ ํญ์ ํจ๊ป ์ค๋ฒ๋ผ์ด๋ฉํด์ผํ๋ค. (0) | 2021.07.27 |
์ ๋ค๋ฆญ(Generic)์ ๋ํ์ฌ (0) | 2021.07.26 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
JiwonDev
JiwonDev