item 78 leekyunghee - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
synchronized ν€μλ
- λ©μλλ λΈλ‘μ νλ²μ ν μ€λ λμ© μννλλ‘ λ³΄μ₯νλ €λ©΄
synchronized
ν€μλλ₯Ό μ¬μ©νλ©΄ λλ€. - λκΈ°νλ₯Ό μ λλ‘ μ¬μ©νλ©΄ μ΄λ€ λ©μλλ κ°μ²΄μ μνκ° μΌκ΄λμ§ μμ μκ°μ λ³Ό μ μλ€.
- λκΈ°νλ λ©μλλ λΈλ‘μ λ€μ΄κ° μ€λ λκ° κ°μ λ½μ 보νΈνμ μνλ λͺ¨λ μ΄μ μμ μ μ΅μ’ κ²°κ³Όλ₯Ό κ°κ² νλ€.
- μ±κΈ μ€λ λ κΈ°λ° νλ‘κ·Έλ¨μ΄λΌλ©΄ λκΈ°νλ₯Ό κ³ λ €νμ§ μμλ λμ§λ§ λ©ν° μ€λ λ κΈ°λ°μ΄λΌλ©΄ κ°μ²΄λ₯Ό 곡μ ν λ λκΈ°νλ₯Ό κ³ λ―Όν΄μΌ νλ€.
μμμ (atomic)
- μλ° μΈμ΄μ λͺ μΈμμΌλ‘ longκ³Ό double λ₯Ό μ μΈν λ³μλ₯Ό μ½κ³ μ°λ κ²μ μμμ μ΄λ€.
- μ¦, λκΈ°ν μμ΄ μ¬λ¬ μ€λ λκ° κ°μ λ³μλ₯Ό μμ νλλΌλ νμ μ΄λ€ μ€λ λκ° μ μμ μΌλ‘ μ μ₯ν κ°μ μ½μ΄μ€λ κ²μ 보μ₯νλ€λ κ²μ΄λ€.
- νμ§λ§ μ€λ λκ° νλλ₯Ό μ½μ λ νμ βμμ μ΄ μμ ν λ°μλβ κ°μ μ»λλ€ λ³΄μ₯νμ§λ§, ν μ€λ λκ° μ μ₯ν κ°μ΄ λ€λ₯Έ μ€λ λμκ² β보μ΄λκ°βλ 보μ₯νμ§ μλλ€. λ°λΌμ μμμ λ°μ΄ν°λ₯Ό μΈ λλ λκΈ°νν΄μΌ νλ€.
μλͺ»λ μ½λ μμ: λκΈ°νκ° μλ€.
- λκΈ°νκ° μλͺ» λμμ λλ μ΄λ€ μΌμ΄ λ°μνλμ§ μ½λλ‘ μ΄ν΄λ³΄μ. μλ μ½λλ μΌλ§λ μ€λ«λμ μ€νλ κΉ?
public class StopThread {
private static boolean stopRequested;
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(() -> {
int i = 0;
while (!stopRequested)
i++;
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}
- μ€λ λκ° start λκ³ 1μ΄ λμμ sleepμ΄ λλλ©΄ boolean λ³μμ κ°μ΄ trueκ° λμ΄ λ£¨νλ₯Ό λΉ μ Έλμ¬ κ²μΌλ‘ μμλλ€.
- νμ§λ§ μ€μ λ‘ μ½λλ₯Ό μνν΄λ³΄λ©΄ νλ‘κ·Έλ¨μ μ’ λ£λμ§ μλλ€.
- λκΈ°νλ₯Ό νμ§ μμκΈ° λλ¬Έμ λ©μΈ μ€λ λκ° μμ ν boolean λ³μμ κ°μ΄ λ°±κ·ΈλΌμ΄λ μ€λ λμκ² μΈμ λ³κ²½λ κ°μΌλ‘ 보μΌμ§ λͺ¨λ₯Έλ€.
- λν λκΈ°ν μ½λκ° μλ€λ©΄ JVMμμ μλμ κ°μ μ΅μ νλ₯Ό ν μλ μλ€.
// μλ μ½λ
while (!stopRequested)
i++;
// μ΅μ νν μ½λ
if (!stopRequested)
while (true)
i++;
- μ΄λ JVMμ΄ μ€μ λ‘ μ μ©νλ λμ΄μ¬λ¦¬κΈ°(hoisting, νΈμ΄μ€ν )λΌλ μ΅μ ν κΈ°λ²μ΄ μ¬μ©λ κ²μ΄λ€.
- κ²°κ³Όμ μΌλ‘ μλ΅ λΆκ°(liveness failure) μνκ° λμ΄ λ μ΄μ μ§νλλ μ½λκ° μλ€. λ€μ κΈ°μ‘΄ μ½λλ‘ λμμμ μκ°ν΄λ³΄λ©΄, 곡μ νλ λ³μλ₯Ό λ€λ£° λ λκΈ°ννλ μ½λλ₯Ό λ£μΌλ©΄ λλ€.
public class StopThread {
private static boolean stopRequested;
private static synchronized void requestStop() {
stopRequested = true;
}
private static synchronized boolean stopRequested() {
return stopRequested;
}
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(() -> {
int i = 0;
while (!stopRequested())
i++;
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
requestStop();
}
}
- μ΄μ²λΌ λκΈ°νλ μ½κΈ°μ μ°κΈ°μ λν΄ λͺ¨λ νμνλ€. μ μ½λμ²λΌ 곡μ νλμ λν μ½κΈ°/μ°κΈ° λ©μλ λͺ¨λλ₯Ό λκΈ°ν μ²λ¦¬νλ©΄ λ¬Έμ λ ν΄κ²°λλ€.
volatile
- λ°°νμ μνκ³Όλ μκ΄μ΄ μμ§λ§ νμ κ°μ₯ μ΅κ·Όμ μ μ₯λ κ°μ μ½μ΄μ¨λ€. μ΄λ‘ μ μΌλ‘λ CPU μΊμκ° μλ μ»΄ν¨ν°μ λ©μΈ λ©λͺ¨λ¦¬λ‘λΆν° κ°μ μ½μ΄μ¨λ€.
- κ·Έλ κΈ° λλ¬Έμ μ½κΈ°/μ°κΈ° λͺ¨λκ° λ©μΈ λ©λͺ¨λ¦¬μμ μνλλ€.
public class stopThread {
private static volatile boolean stopRequested;
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(() -> {
int i = 0;
while (!stopRequested)
i++;
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}
- μ μ½λμ²λΌ volatileμ μ¬μ©νλ©΄ λκΈ°νλ₯Ό μλ΅ν΄λ λλ€. λ€λ§ μ£Όμν΄μ μ¬μ©ν΄μΌ νλ€. μλμ κ°μ μμ μμ λ¬Έμ μ μ μ°Ύμλ³Ό μ μλ€.
private static volatile int nextSerialNumber = 0;
public static int generateSerialNumber() {
return nextSerialNumber++;
}
- μ½λμμΌλ‘ μ¦κ° μ°μ°μ(++)λ νλμ§λ§ μ€μ λ‘λ volatile νλμ λ λ² μ κ·Όνλ€.
- λ¨Όμ κ°μ μ½κ³ , κ·Έ λ€μμ 1μ μ¦κ°ν ν μλ‘μ΄ κ°μ μ μ₯νλ κ²μ΄λ€.
- λ°λΌμ λ λ²μ§Έ μ€λ λκ° μ²« λ²μ§Έ μ€λ λμ μ°μ° μ¬μ΄μ λ€μ΄μ 곡μ νλλ₯Ό μ½κ² λλ©΄, 첫 λ²μ§Έ μ€λ λμ κ°μ κ°μ 보κ²λ κ²μ΄λ€.
- μ΄μ²λΌ μλͺ»λ κ²°κ³Όλ₯Ό κ³μ°ν΄λ΄λ μ€λ₯λ₯Ό μμ μ€ν¨(safety failure)λΌκ³ νλ€. μ΄ λ¬Έμ λ λ©μλμ synchronizedλ₯Ό λΆμ΄κ³ volatile ν€μλλ₯Ό 곡μ νλμμ μ κ±°νλ©΄ ν΄κ²°λλ€.
atomic ν¨ν€μ§
- java.util.concurrent.atomic ν¨ν€μ§μλ λ½ μμ΄λ thread-safeν ν΄λμ€λ₯Ό μ 곡νλ€.
- volatileμ λκΈ°νμ ν¨κ³Ό μ€ ν΅μ μͺ½λ§ μ§μνμ§λ§ μ΄ ν¨ν€μ§λ μμμ±(λ°°νμ μ€ν)κΉμ§ μ§μνλ€. κ²λ€κ° μ±λ₯λ λκΈ°ν λ²μ λ³΄λ€ μ°μνλ€.
private static final AtomicLong nextSerialNum = new AtomicLong();
public static long generateSerialNumber() {
return nextSerialNum.getAndIncrement();
}
ν΅μ¬μ 리
- κ²°λ‘ μ μΌλ‘λ κ°λ³ λ°μ΄ν°λ₯Ό 곡μ νμ§ μλ κ²μ΄ λκΈ°ν λ¬Έμ λ₯Ό νΌνλ κ°μ₯ μ’μ λ°©λ²μ΄λ€.
- μ¦, κ°λ³ λ°μ΄ν°λ λ¨μΌ μ€λ λμμλ§ μ¬μ©νμ. ν μ€λ λκ° λ°μ΄ν°λ₯Ό μμ ν νμ λ€λ₯Έ μ€λ λμ 곡μ ν λλ ν΄λΉ κ°μ²΄μμ 곡μ νλ λΆλΆλ§ λκΈ°νν΄λ λλ€.
- λ€λ₯Έ μ€λ λμ μ΄λ° κ°μ²΄λ₯Ό 건λ€λ νμλ₯Ό μμ λ°ν(safe publication)μ΄λΌκ³ νλ€.
- ν΄λμ€ μ΄κΈ°ν κ³Όμ μμ κ°μ²΄λ₯Ό μ μ νλ, volatile νλ, final νλ νΉμ 보ν΅μ λ½μ ν΅ν΄ μ κ·Όνλ νλ κ·Έλ¦¬κ³ λμμ± μ»¬λ μ μ μ μ₯νλ©΄ μμ νκ² λ°νν μ μλ€.