Chapter 11 λμμ±
λμμ± νλ‘κ·Έλλ°μ λ¨μΌ μ€λ λ νλ‘κ·Έλλ°λ³΄λ€ μ΄λ ΅λ€.
μλͺ»λ μ μλ μΌμ΄ λμ΄λκ³ λ¬Έμ λ₯Ό μ¬ννκΈ°λ μ΄λ ΅κΈ° λλ¬Έμ΄λ€. νμ§λ§ νμ¬μ λ©ν°μ½μ΄ νλ‘μΈμ€λ₯Ό μ νμ©νλ €λ©΄ λ°λμ μ΅νμΌ νλ κΈ°μ μ΄λ€.
Item 78 곡μ μ€μΈ κ°λ³ λ°μ΄ν°λ λκΈ°νν΄ μ¬μ©νλΌ
μ¬μ©μ€μΈ μ€λ λλ₯Ό λ©μΆλ Thread.stop
λ©μλλ μ¬μ©νμ§ λ§μ.
λ€μμ μ€λ λλ₯Ό λ©μΆλ μ¬λ°λ₯Έ λ°©λ²μ΄λ€.
- μμ μ
boolean
νλλ₯Ό ν΄λ§νλ©΄μ κ·Έ κ°μ΄true
κ° λλ©΄ λ©μΆλ€. - μ΄
boolean
νλλ₯Όfalse
λ‘ μ΄κΈ°ν ν΄λκ³ λ€λ₯Έ μ€λ λμμ μ΄ μ€λ λλ₯Ό λ©μΆκ³ μ ν λ true λ‘ λ³κ²½νλ€.
boolean
νλλ₯Ό μ½κ³ μ°λ μμ μ μμμ μ΄λ€.
μλ μ½λλ 무ννκ² μ€νλλ μ½λμ΄λ€.
public class StopThread {
private static boolean stopRequest;
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(() -> {
int i = 0;
while(!stopRequest)
i++;
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}
μ μ½λμμ stopRequest
νλμ μ½κΈ°μ μ°κΈ° μμ
μ λκΈ°νν΄ μ κ·Όν΄μΌ νλ€.
public class StopThread {
private static boolean stopRequest;
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
νμ μλ λ² νμ μνκ³Όλ κ΄κ³ μμ§λ§ νμ κ°μ₯ μ΅κ·Όμ κΈ°λ‘λ κ°μ μ½λλ‘ λ³΄μ₯νλ€.
public class StopThread {
private static volatile boolean stopRequest;
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;
}
}
InterruptedException
InterruptedException
λ νμ¬ μ€νμ€μΈ μ€λ μ΄λμμ Thread.interrupt()
λ₯Ό νΈμΆν λκ΅°κ°λ₯Ό μλ―Ένλ€.
ν΄λΉ μ΄λ²€νΈκ° μΌμ΄λλ€λ©΄ μλμ κ°μ΄ μ΅λν 빨리 μ’ λ£ν΄μΌ νλ€.
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new AssertionError(e);
}
μ μ½λλ throw
λκΈ° μ΄μ μ μ€λ λ μΈν°λ½νΈ μνλ₯Ό λ¨Όμ 볡μν λ€μμ κΈ°λ³Έ invariant κ° μλ°λμμμ λνλ΄λ AssertionError
μ throw
νλ€.
https://riptutorial.com/ko/java/example/2116/interruptedexceptionμ-μ²λ¦¬
κ°μ₯ μ’μ λ°©λ²μ κ°λ³ λ°μ΄ν°λ λ¨μΌ μ€λ λμμλ§ μ¬μ©νλλ‘ νλ©° λΆλ³ λ°μ΄ν°λ§ 곡μ νκ±°λ μ무κ²λ 곡μ ν΄μλ μλλ€.
Item 79 κ³Όλν λκΈ°νλ νΌν΄λΌ
κ³Όλν λκΈ°νλ μ±λ₯μ λ¨μ΄λ¨λ¦¬κ³ , κ΅μ°©μνμ λΉ λ¨λ¦¬λ©° μ¬μ§μ΄ μμΈ‘ λΆκ°λ₯ν λμμ λ¨κΈΈμλ μλ€.
μλ΅ λΆκ° νΉμ μμ μ€ν¨ (Safe Failure) μ νΌνλ €λ©΄ λκΈ°ν λ©μλλ λκΈ°ν λΈλ μμ μ μ΄λ₯Ό ν΄λΌμ΄μΈνΈμκ² μλνλ©΄ μλλ€.
- λκΈ°ν μμ μμλ μ¬μ μ ν μμλ λ©μλλ νΈμΆνλ©΄ μλλ€.
- ν΄λΌμ΄μΈνΈκ° λκ²¨μ€ ν¨μ κ°μ²΄λ₯Ό νΈμΆν΄μλ μλλ€.
μΈλΆμ λ©μλλ μ΄λ ν μΌμ ν μ μλμ§ λ³΄μ₯νκΈ° μ΄λ €μ μμΈ, κ΅μ°©μν, λ°μ΄ν°μ νΌμμ μΌκΈ°μν¬μλ μλ€.
λλ¬Έμ λκΈ°ν μμμμλ κ°λ₯ν μΌμ μ κ² νλκ²μ΄λ€.
κ°λ³ ν΄λμ€λ₯Ό μμ±νλ €κ±°λ λ€μ λκ°μ§μ λ°©λ²μ΄ μλ€.
- λκΈ°νλ₯Ό μ ν νμ§ λ§κ³ κ·Έ ν΄λμ€λ₯Ό λμμ μ¬μ©νλ ν΄λμ€κ° μΈλΆμμ μμμ λκΈ°ν νκ² λ§λ€μ
- λκΈ°νλ₯Ό λ΄λΆμμ μνν΄ Thread Safe ν ν΄λμ€λ‘ λ§λ€μ
StringBuffer
μΈμ€ν΄μ€λ λ¨μΌ μ€λ λ μμλ λΆκ΅¬νκ³ λ΄λΆμ μΌλ‘ λκΈ°νλ₯Ό μννλ€
λλ¬Έμ StringBuilder
λ₯Ό ν΅νμ¬ λκΈ°νλ₯Ό μ κ±°νμλ€. (StringBuffer
- λκΈ°ν = StringBuilder
)
java.util.Random
λ μ΄μ λμΌν μ΄μ λ‘ java.util.concurrent.ThreadLocalRandom
μΌλ‘ λ체 λμλ€.
Item 80 μ€λ λ보λ€λ μ€νμ, νμ€ν¬, μ€νΈλ¦Όμ μ μ©νλΌ.
java.util.concurrent
μ ν¨ν€μ§λ μ€νμ νλ μμν¬ (Executor Framework) λΌκ³ νλ μΈν°νμ΄μ€ κΈ°λ°μ μ μ°ν νμ€ν¬ μ€ν κΈ°λ₯μ λ΄κ³ μλ€.
// μ€νμ μμ±
ExecutorService exec = Executors.newSingleThreadExecutor();
// μ€νμμ νμ€ν¬λ₯Ό λκΉ
exec.execute(runnable);
// μ€νμ μ’
λ£
exec.shutdown();
λλΆλΆμ λμμ± νλ‘κ·Έλλ°μ μ΄μ©μ java.util.concurrent
ν¨ν€μ§ λ΄μμ λμμ λ°μμ μλ€.
Item 81 waitμ notify보λ€λ λμμ± μ νΈλ¦¬ν°λ₯Ό μ μ©νλΌ.
java.util.concurrent
μ κ³ μμ€ μ νΈλ¦¬ν°λ μΈκ°μ§ λ²μ£Όλ‘ λλμ μλ€.
- μ€νμ νλ μμν¬ (Executor Framework)
- λμμ± μ»¬λ μ (Concurrent Collection)
- λκΈ°ν μ₯μΉ (Synchronizer)
λμμ± μ»¬λ μ
μ List
Queue
Map
κ³Ό κ°μ νμ€ μ»¬λ μ
μΈν°νμ΄μ€μ λμμ±μ κ°λ―Έν΄ ꡬνν΄ λμ κ³ μ±λ₯ 컬λ μ
μ΄λ€.
λμ λμμ±μ λλ¬νκΈ° μν΄ λκΈ°νλ₯Ό κ°κ° λ΄λΆμμ μννλ€.
λ°λΌμ λμμ± μ»¬λ μ μμ λμμ±μ 무λ ₯ννλκ²μ λΆκ°λ₯νλ©°, μΈλΆμμ λ½μ μΆκ°λ‘ μ¬μ©νλ©΄ μ€νλ € μλκ° λλ €μ§λ€.
Java SE 8 μμλ μΈν°νμ΄μ€μ λν΄νΈ λ©μλκ° μΆκ°λμλλ° Map
μ pushIfAbsent(key, value)
κ° λνμ μΈ μμΈλ€.
pushIfAbsent(key, value)
λ μ£Όμ΄μ§ ν€μ 맀νλ κ°μ΄ μμ§ μμλλ§ μ§μ΄ λ£λλ€.
κΈ°μ‘΄ κ°μ΄ μμλ€λ©΄ κ·Έ κ°μ λ°ννκ³ μμλ€λ©΄ null
μ λ°ννλ€.
μλ μ½λλ ConcurrentMap
μΌλ‘ ꡬνν λμμ± μ κ·ν 맡μ΄λ€.
private static final ConcurrentMap<String, String> map = new ConcurrentHashMap<>();
public static String intern(String str) {
String previousValue = map.putIfAbsent(str, str);
return previousValue == null ? str : previousValue;
}
μ μ½λμμ ConcurrentHashMap
μ get()
κ²μ κΈ°λ₯μ΄ μ΅μ ν λμ΄ μμΌλ―λ‘ λ¨Όμ get μ νΈμΆνμ¬ putIfAbsent
μ νΈμΆνλ©΄ λ λΉ λ₯΄λ€.
public static String intern(String str) {
String result = map.get(str);
if (result == null) {
result = map.putIfAbsent(str, str);
if (result == null)
result = str;
}
return result;
}
λκΈ°νν 컬λμΌ λ§΅λ³΄λ€ λμμ± μ»¬λ μ
μ΄ μ±λ₯μ μΌλ‘ λ μ°μνλ€.
μ¦ Collections.synchronizedMap
λ³΄λ€ ConcurrentHashMap
μ μ¬μ©νλκ²μ΄ ν¨μ¬ μ’λ€.
μκ° κ°κ²©μ μ΄ λλ νμ System.currentTimeMillis
κ° μλ System.nanotime
μ μ¬μ©νμ
System.nanotime
μ λ μ ννκ³ μ λ°νλ©° μμ€ν
μ μ€μκ° μκ³μ μκ° λ³΄μ μ μν₯μ λ°μ§ μλλ€.
Item 82 μ€λ λ μμ μ± μμ€μ λ¬Έμν νλΌ
ꡬν λ©μλμ synchronized
νμ μκ° ν¬ν¨λμ΄ μλ€κ³ ν΄λ λ©μλ ꡬννλ κ³Όμ μμ μ¬μ©ν λΏμ΄λ©° ν΄λΉ κΈ°λ₯μ 보μ₯ν μ μλ€.
λλ¬Έμ λ©ν°μ€λ λ νκ²½μμ APIλ₯Ό μμ νκ² μ¬μ©νλ €λ©΄ ν΄λμ€κ° μ§μνλ μ€λ λ μμ μ± μμ€μ μ νν λͺ μν΄μΌ νλ€.
Collections.synchronizedMap
μ μ¬μ©λλ API λ¬Έμλ₯Ό μ°Έκ³ ν΄λ³΄λ©΄ λ€μκ³Ό κ°μ΄ μ¨μλ€.
// synchronizedMap μ΄ λ°νν 맡μ 컬λ μ
λ·°λ₯Ό μννλ €λ©΄ λ°λμ κ·Έ 맡μ λ½μΌλ‘ μ¬μ©ν΄ μλμΌλ‘ λκΈ°ννλΌ
Map<K, V> m = Collections.synchronizedMap(new HashMap<>());
Set<K, V> s = m.keySet();
...
synchronized(m) {
for (K key: s) {
key.f();
}
}
// μ΄λλ‘ λ°λ₯΄μ§ μμΌλ©΄ λμμ μμΈ‘ν μ μλ€.
μ€λ λμ μμ μ±μ λ³΄ν΅ ν΄λμ€μ λ¬Έμν μ£Όμμ κΈ°μ¬νμ§λ§, νΉμ λ©μλμ νν΄μλ ν΄λΉ λ©μλ μ£Όμμ κΈ°μ¬νλλ‘ νμ.
Item 83 νλ‘κ·Έλ¨μ λμμ μ€λ λ μ€μΌμ€λ¬μ κΈ°λμ§ λ§λΌ
μ¬λ¬ μ€λ λκ° μ€ν μ€μ΄λ©΄ μ΄μ체μ μ μ€λ λ μ€μΌμ€λ¬κ° μ΄λ€ μ€λ λλ₯Ό μΌλ§λ μ€λ μ€νν μ§ μ νλ€.
μ μμ μΈ μ΄μ 체μ λΌλ©΄ μ΄ μμ μ 곡μ νκ² μννμ§λ§ μ€μΌμ€λ§ μ μ± μ μ΄μ체μ λ§λ€ λ€λ₯΄λ©° μ μμ±λ νλ‘κ·Έλ¨μ΄λΌλ©΄ μ΄ κΈ°μ€ μ μ± μ μμ‘΄ν΄μλ μλλ€.
μ νμ±μ΄λ μ±λ₯μ΄ μ€λ λ μ€μΌμ€λ¬μ λ°λΌ λ¬λΌμ§λ νλ‘κ·Έλ¨μ΄λΌλ©΄ λ€λ₯Έ νλ«νΌμ μ΄μνκΈ° μ΄λ ΅λ€.