Synchronized
Javaλ λ©ν° μ€λ λ νκ²½μμ λμμ± μ μ΄λ₯Ό νκΈ° μν΄ μ¬λ¬ λ°©λ²μ μ§μνλ€.
β’
Lock
β’
Synchronized
β’
Concurrent Collections
β’
λ±λ±
Synchronizedλ λμμ± μ μ΄λ₯Ό μν κ°μ₯ κΈ°μ΄μ μΈ λ°©λ²μΌλ‘, νΉμ κ°μ²΄λ₯Ό μ κΈ(lock)μΌλ‘μ¨ μκ³ μμμ μ€μ νλ€.
synchronized(obj) {
// μκ³ μμ(critical section)
}
Java
볡μ¬
λ©μλ λμμΌλ‘ Synchronizedλ₯Ό μ¬μ©ν μ μμ§λ§ μ΄ λν ν΄λμ€ κ°μ²΄λ₯Ό μ κΈ(lock) νμ¬ μκ³ μμμ μ€μ νλ κ²μ΄λ€.
class foo {
synchronized void someAction() {
// code
}
}
class foo {
void someAction() {
synchronized(this) {
// code
}
}
}
Java
볡μ¬
μ£Όμ μ¬ν
νμ§λ§ Synchronizedμ μ κΈ κ°μ²΄λ₯Ό λ¬Έμμ΄(String)μ μ¬μ©νλ κ²½μ° μ£Όμκ° νμνλ€.
λ§μ½ λ€μκ³Ό κ°μ΄ λ¬Έμμ΄μ β+β μ°μ°μλ‘ ν©μΉκ³ μ κΈ κ°μ²΄λ‘ μ¬μ©ν κ²½μ° λ¬Έμ κ° λ°μνλ€.
public class SynchronizedString {
private int value = 0;
public void incrementValue(long id) {
synchronized ("lock" + id) {
value++;
System.out.println("value: " + value);
}
}
public int getValue() {
return value;
}
}
@Test
@DisplayName("λ¬Έμμ΄ λκΈ°ν ν
μ€νΈ")
void test_synchronized_string() throws InterruptedException {
// given
SynchronizedString synchronizedString = new SynchronizedString();
// when
int count = 10000;
ExecutorService executorService = Executors.newFixedThreadPool(20);
CountDownLatch countDownLatch = new CountDownLatch(count);
for (int i = 0; i < count; i++) {
executorService.execute(() -> {
synchronizedString.incrementValue(1L);
countDownLatch.countDown();
});
}
countDownLatch.await();
// then
// ν
μ€νΈκ° μ€ν¨νλ€.
assertEquals(count, synchronizedString.getValue());
}
Java
볡μ¬
μ΄μ λ (βlockβ + id) λΆλΆ λλ¬Έμ΄λ€. Javaμμ λ¬Έμμ΄μ λΆλ³μ±(immutable)μ κ°μ§λλ°, μ΄ νΉμ±μΌλ‘ λ¬Έμμ΄μ νλ² μμ±λλ©΄ μμ μ΄ λΆκ°λ₯νκ³ β+β μ°μ°μλ₯Ό μ¬μ©νκ² λλ€λ©΄ μλ‘μ΄ λ¬Έμμ΄ κ°μ²΄λ₯Ό μμ±νκ² λλ€. κ·Έλμ ν λ©λͺ¨λ¦¬ μ μ£Όμκ° λ€λ₯΄κΈ° λλ¬Έμ λμΌ κ°μ²΄λ‘ μΈμνμ§ μμ μ μμ μΌλ‘ λκΈ°νκ° λμ§ μλλ€.
μ€λ λλ§λ€ μλ‘μ΄ λ¬Έμμ΄μ lockμ 건λ€.
ν΄κ²° λ°©λ²
ν΄κ²° λ°©λ²μ μλ‘ μμ±ν λ¬Έμμ΄μ λν΄ lockμ κ±°λ κ² μλ, String Poolμ μλ λ¬Έμμ΄μ λν΄ lockμ κ±°λ κ²μ΄λ€. Spring Poolμ μ κ·ΌνκΈ° μν΄μλ intern() λ©μλλ₯Ό μ¬μ©νλ€. intern() λ©μλλ₯Ό νΈμΆνλ©΄ String Poolμ μ‘΄μ¬νλ λ¬Έμμ΄μ΄λΌλ©΄ νμ λ¬Έμμ΄μ λ°ννκ³ , μλ€λ©΄ νμ λ±λ‘ ν λ°ννλ€.
public void incrementValueWithIntern(long id) {
synchronized (("lock" + id).intern()) {
value++;
System.out.println("value: " + value);
}
}
Java
볡μ¬
intern() λ©μλλ‘ λμΌν λ¬Έμμ΄μ lockμ 건λ€.
μμ€ μ½λ
λΆλ‘
μ€μ λ‘ κ°λ° μ λ¬Έμμ΄μ synchronized κ°μ²΄λ‘ μ¬μ©ν μΌμ λλ¬Όκ±°λ μκ² μ§λ§, λμμ± κ΅¬ν κ³Όμ λ₯Ό μ§ννλ©΄μ μκ² λ μ¬μ€μ΄λ€. μλλ String Poolκ³Ό intern()μ λν΄μ μκ³ μμμ§λ§ μ²μ κ²ͺμ μΌμ΄μ€λΌ μ 리νκ² λλ€.
intern() λ©μλλ₯Ό μ¬μ©νλ©΄ κ²°κ΅ String Poolμ μλ λ¬Έμμ΄μ λΉκ΅ν ν
λ° κ·ΈλΌ μλκ° λ λλ¦¬μ§ μμκΉ νμ¬ κ²μν΄λ³Έ λ΄μ©μ΄λ€.
κ²°λ‘ μ intern() λ©μλλ λ¬Έμμ΄ νμ μλ κ°μ λν΄ equals()μ μννκΈ° λλ¬Έμ μλ μΈ‘λ©΄μμλ λ릴 μλ°μ μλ€.