item 78 incheol - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
Effective Java 3e μμ΄ν 68λ₯Ό μμ½ν λ΄μ© μ λλ€.
synchronized ν€μλλ ν΄λΉ λ©μλλ λΈλ‘μ νλ²μ ν μ€λ λμ© μννλλ‘ λ³΄μ₯νλ€. μ¦ ν μ€λ λκ° λ³κ²½νλ μ€μ΄λΌμ μνκ° μΌκ΄λμ§ μμ μκ°μ κ°μ²΄λ₯Ό λ€λ₯Έ μ€λ λκ° λ³΄μ§ λͺ»νκ² λ§λ μ©λλ‘λ§ μκ°νλ€.
λκΈ°νλ₯Ό μ λλ‘ μ¬μ©νλ©΄ μ΄λ€ λ©μλλ μ΄ κ°μ²΄μ μνκ° μΌκ΄λμ§ μμ μκ°μ λ³Ό μ μκ³ μ€λ λκ° λ§λ λ³νλ₯Ό λ€λ₯Έ μ€λ λμμ νμΈνμ§ λͺ»ν μ μλ€.
longκ³Ό double μΈμ λ³μλ₯Ό μ½κ³ μ°λ λμμ μμμ (atomic)μ΄λ€. μ΄ λ§μ λ£κ³ **"μ±λ₯μ λμ΄λ €λ©΄ μμμ λ°μ΄ν°λ₯Ό μ½κ³ μΈ λλ λκΈ°ννμ§ λ§μμΌκ² λ€"**κ³ μκ°νκΈ° μ¬μ΄λ°, μμ£Ό μνν λ°μμ΄λ€.
λκΈ°νλ λ°°νμ μ€νλΏ μλλΌ μ€λ λ μ¬μ΄μ μμ μ μΈ ν΅μ μ κΌ νμνλ€.
곡μ μ€μΈ κ°λ³ λ°μ΄ν°λ₯Ό λΉλ‘ μμμ μΌλ‘ μ½κ³ μΈ μ μμμ§λΌλ λκΈ°νμ μ€ν¨νλ©΄ μ²μ°Έν κ²°κ³Όλ‘ μ΄μ΄μ§ μ μλ€. λ€μ μ€λ λλ₯Ό μ€μ§νλ μ½λλ₯Ό μ΄ν΄λ³΄μ
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;
}
}
μμ μ½λλ₯Ό 보면 1μ΄ ν stopRequestedλ₯Ό trueλ‘ μ€μ νλ©΄ backgroundTreadλ λ°λ³΅λ¬Έμ λΉ μ Έλμ¬ κ²μ²λΌ λ³΄μΌ κ²μ΄λ€. νμ§λ§ λ΄ μ»΄ν¨ν°μμλ λν΅ λλ μ€ λͺ¨λ₯΄κ³ μμν μνλμλ€. μμΈμ λκΈ°ννμ§ μμΌλ©΄ λ©μΈ μ€λ λκ° μμ ν κ°μ λ°±κ·ΈλΌμ΄λ μ€λ λκ° μΈμ μ―€μλ λ³΄κ² λ μ§ λ³΄μ¦ν μ μλ€. λκΈ°νκ° λΉ μ§λ©΄ κ°μ λ¨Έμ μ΄ λ€μκ³Ό κ°μ μ΅μ νλ₯Ό μνν μλ μλ κ²μ΄λ€.
if (!stopRequested)
while (true)
i++;
μ΄λ stopRequested νλλ₯Ό λκΈ°νν΄ μ κ·Όνλ©΄ μ΄ λ¬Έμ λ₯Ό ν΄κ²°ν μ μλ€.
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();
}
}
λ°λ³΅λ¬Έμμ λ§€λ² λκΈ°ννλ λΉμ©μ΄ ν¬μ§ μμ§λ§ μλκ° λ λΉ λ₯Έ λμμ΄ μλ€. stopRequested νλλ₯Ό volatileμΌλ‘ μ μΈνλ©΄ λκΈ°νλ₯Ό μκ°ν΄λ λλ€. volatile νμ μλ λ°°νμ μνκ³Όλ μκ΄μμ§λ§ νμ κ°μ₯ μ΅κ·Όμ κΈ°λ‘λ κ°μ μ½κ² λ¨μ 보μ₯νλ€.
public class StopThread {
private static volatile boolean stopRequested;
public static void main(String[] args) throws InterruptedException {
Thread backgroudThread = new Tread(() -> {
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++;
}
μ΄ λ©μλλ λ§€λ² κ³ μ ν κ°μ λ°νν μλλ‘ λ§λ€μ΄μ‘λ€. λ¬Έμ λ μ¦κ° μ°μ°μ(++)λ€. μ΄ μ°μ°μλ μ½λμμΌλ‘λ νλμ§λ§ μ€μ λ‘λ nextSerialNumber νλμ λ λ² μ κ·Όνλ€. λ§μ½ λ λ²μ§Έ μ€λ λκ° μ΄ λ μ κ·Ό μ¬μ΄λ₯Ό λΉμ§κ³ λ€μ΄μ κ°μ μ½μ΄ κ°λ©΄ 첫 λ²μ§Έ μ€λ λμ λκ°μ κ°μ λλ €λ°κ² λλ€. νλ‘κ·Έλ¨μ΄ μλͺ»λ κ²°κ³Όλ₯Ό κ³μ°ν΄λ΄λ μ΄λ° μ€λ₯λ₯Ό μμ μ€ν¨νκ³ νλ€. μ΄λ synchronized νμ μλ₯Ό λΆμ΄λ©΄ ν΄κ²°λλ€. μ΄ λ©μλλ₯Ό λ κ²¬κ³ νκ² νλ €λ©΄ int λμ μ longμ μ¬μ©νκ±°λ nextSerialNumberκ° μ΅λκ°μ λλ¬νλ©΄ μμΈλ₯Ό λμ§κ² νμ.
λλ AtomicLongμ μ¬μ©νλ©΄ λ½ μμ΄λ μ€λ λ μμ ν νλ‘κ·Έλλ°μ μ§μνλ€. volatileμ λκΈ°νμ λ ν¨κ³Ό μ€ ν΅μ μͺ½λ§ μ§μνμ§λ§ μ΄ ν¨ν€μ§λ μμμ±κΉμ§ μ§μνλ€. κ·Έλ¦¬κ³ μ±λ₯λ λκΈ°ν λ²μ λ³΄λ€ μ°μνλ€.
private static final AtomicLong nextSerialNumber = 0;
public static int generateSerialNumber() {
return nextSerialNumber++;
}
λ€μ λ§ν΄ κ°λ³ λ°μ΄ν°λ λ¨μΌ μ€λ λμμλ§ μ°λλ‘ νμ.
κ·Έλ¦¬κ³ μ΄ μ¬μ€μ λ¬Έμμ λ¨κ²¨ μ μ§λ³΄μ κ³Όμ μμλ μ μ±
μ΄ κ³μ μ§μΌμ§λλ‘ νλ κ² μ€μνλ€. λν, μ¬μ©νλ €λ νλ μμν¬μ λΌμ΄λΈλ¬λ¦¬λ₯Ό κΉμ΄ μ΄ν΄νλ κ²λ μ€μνλ€.
ν μ€λ λκ° λ°μ΄ν°λ₯Ό λ€ μμ ν ν λ€λ₯Έ μ€λ λμ 곡μ ν λλ ν΄λΉ κ°μ²΄μμ 곡μ νλ λΆλΆλ§ λκΈ°νν΄λ λλ€. κ·Έλ¬λ©΄ κ·Έ κ°μ²΄λ₯Ό λ€μ μμ ν μΌμ΄ μκΈ°κΈ° μ κΉμ§ λ€λ₯Έ μ€λ λλ€μ λκΈ°ν μμ΄ μμ λ‘κ² κ°μ μ½μ΄κ° μ μλ€.
ν΄λμ€ μ΄κΈ°ν κ³Όμ μμ κ°μ²΄λ₯Ό μ μ νλ, volatile νλ, final νλ, νΉμ 보ν΅μ λ½μ ν΅ν΄ μ κ·Όνλ νλμ μ μ₯ν΄λ λλ€.
μ 리
μ¬λ¬ μ€λ λκ° κ°λ³ λ°μ΄ν°λ₯Ό 곡μ νλ€λ©΄ κ·Έ λ°μ΄ν°λ₯Ό μ½κ³ μ°λ λμμ λ°λμ λκΈ°νν΄μΌ νλ€. λκΈ°ννμ§ μμΌλ©΄ ν μ€λ λκ° μνν λ³κ²½μ λ€λ₯Έ μ€λ λκ° λ³΄μ§ λͺ»ν μλ μλ€. 곡μ λλ κ°λ³ λ°μ΄ν°λ₯Ό λκΈ°ννλ λ° μ€ν¨νλ©΄ μλ΅ λΆκ° μνμ λΉ μ§κ±°λ μμ μ€ν¨λ‘ μ΄μ΄μ§ μ μλ€. μ΄λ λλ²κΉ
λμ΄λκ° κ°μ₯ λμ λ¬Έμ μ μνλ€. κ°νμ μ΄κ±°λ νΉμ νμ΄λ°μλ§ λ°μν μλ μκ³ , VMμ λ°λΌ νμμ΄ λ¬λΌμ§κΈ°λ νλ€. λ°°νμ μ€νμ νμ μκ³ μ€λ λ λΌλ¦¬μ ν΅μ λ§ νμνλ€λ©΄ volatile νμ μλ§μΌλ‘ λκΈ°νν μ μλ€. λ€λ§ μ¬λ°λ‘ μ¬μ©νκΈ°κ° κΉλ€λ‘λ€.