-
Notifications
You must be signed in to change notification settings - Fork 94
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #348 from SujinEmilyCho/week12_sujin
[#82][2κΈ°] μ€λ λ μμ μ± μμ€μ λ¬ΈμννλΌ
- Loading branch information
Showing
1 changed file
with
101 additions
and
0 deletions.
There are no files selected for viewing
101 changes: 101 additions & 0 deletions
101
11μ₯/82_μ€λ λ_μμ μ±_μμ€μ_λ¬ΈμννλΌ_μ‘°μμ§.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# μμ΄ν 82. μ€λ λ μμ μ± μμ€μ λ¬ΈμννλΌ | ||
μλ°λ κΈ°λ³Έ μ΅μ μμ μμ±ν API λ¬Έμμλ synchronized νμ μκ° ν¬ν¨λμ§ μλλ€. λ©μλ μ μΈμ synchronized νμ μλ₯Ό μ μΈν μ§λ ꡬν μ΄μμΌ λΏ APIμ μνμ§ μλλ€. | ||
|
||
### ν΄λμ€κ° μ§μνλ μ€λ λ μμ μ± μμ€ | ||
1. λΆλ³(immutabile) | ||
- μ΄ ν΄λμ€μ μΈμ€ν΄μ€λ λ§μΉ μμμ κ°μμ μΈλΆ λκΈ°νλ νμ μλ€. | ||
- ex. String, Long, BigInteger λ± | ||
2. 무쑰건μ μ€λ λ μμ (unconditionally thread-safe) | ||
- μ΄ ν΄λμ€μ μΈμ€ν΄μ€λ μμ λ μ μμΌλ, λ΄λΆμμ μΆ©μ€ν λκΈ°ννμ¬ λ³λμ μΈλΆ λκΈ°ν μμ΄ λμμ μ¬μ©ν΄λ μμ νλ€. | ||
- ex. AtomicLong, ConcurrentHashMap λ± | ||
3. μ‘°κ±΄λΆ μ€λ λ μμ (contiditionally thread-safe) | ||
- 무쑰건μ μ€λ λ μμ κ³Ό κ°μΌλ, μΌλΆ λ©μλλ λμμ μ¬μ©νλ €λ©΄ μΈλΆ λκΈ°νκ° νμνλ€ | ||
- ex. Collections.synchronized λνΌ λ©μλκ° λ°νν 컬λ μ λ€μ΄ μ¬κΈ°μ μνλ€(μ΄ μ»¬λ μ λ€μ΄ λ°νν λ°λ³΅μλ μΈλΆμμ λκΈ°νν΄μΌ νλ€) | ||
4. μ€λ λ μμ νμ§ μμ(not thread-safe) | ||
- μ΄ ν΄λμ€λ€μ μΈμ€ν΄μ€λ μμ λ μ μλ€. λμμ μ¬μ©νλ €λ©΄ κ°κ°μ(νΉμ μΌλ ¨μ) λ©μλ νΈμΆμ ν΄λΌμ΄μΈνΈκ° μ νν μΈλΆ λκΈ°ν λ©μ»€λμ¦μΌλ‘ κ°μΈμΌ νλ€. | ||
- ex. ArrayList, HashMap κ°μ κΈ°λ³Έ 컬λ μ μ΄ μ¬κΈ° μνλ€. | ||
5. μ€λ λ μ λμ (thread-hostile) | ||
- μ΄ ν΄λμ€λ λͺ¨λ λ©μλ νΈμΆμ μΈλΆ λκΈ°νλ‘ κ°μΈλλΌλ λ©ν°μ€λ λ νκ²½μμ μμ νμ§ μλ€. μ΄ μμ€μ ν΄λμ€λ μΌλ°μ μΌλ‘ μ μ λ°μ΄ν°λ₯Ό μ무 λκΈ°ν μμ΄ μμ νλ€. μ΄λ° ν΄λμ€λ₯Ό κ³ μμ μΌλ‘ λ§λλ μ¬λμ μκ² μ§λ§, λμμ±μ κ³ λ €νμ§ μκ³ μμ±νλ€ λ³΄λ©΄ μ°μ°ν λ§λ€μ΄μ§ μ μλ€. μ€λ λ μ λμ μΌλ‘ λ°νμ§ ν΄λμ€λ λ©μλλ μΌλ°μ μΌλ‘ λ¬Έμ λ₯Ό κ³ μ³ μ¬λ°°ν¬νκ±°λ μ¬μ© μμ (deprecated) APIλ‘ μ§μ νλ€. | ||
- ex. μμ΄ν 78μ generateSerialNumber λ©μλμ λ΄λΆ λκΈ°νλ₯Ό μλ΅ν κ²½μ° | ||
|
||
### μ€λλ μμ μ± μ λν μ΄μ | ||
- `@Immutable` | ||
- `@ThreadSafe`: unconditionally thread-safe, conditionalluy thread-safe | ||
- `@NotThreadSafe` | ||
|
||
### μΈλΆ λκΈ°ν vs λ΄λΆ λκΈ°ν | ||
```java | ||
public class Foo { | ||
private int count; | ||
public void addToCount() { | ||
count++; | ||
log.info("count increased to " + count); | ||
} | ||
} | ||
|
||
// μΈλΆ λκΈ°ν | ||
synchronized (foo) { | ||
foo.addToCount(); | ||
} | ||
``` | ||
|
||
```java | ||
// λ΄λΆ λκΈ°ν | ||
public class Foo { | ||
private int count; | ||
|
||
public void addToCount() { | ||
int val; | ||
synchronized (this) { | ||
val = ++count; | ||
} | ||
// this log call should not be synchronized since it does IO | ||
log.info("count increased to " + val); | ||
} | ||
} | ||
``` | ||
β μΈλΆ λκΈ°ν, λ΄λΆ λκΈ°νλ₯Ό μμ보기 μν μμμΌ λΏ μ€μ λ‘λ AtomicIntegerμ μ¬μ©νλ κ²μ΄ κ°μ₯ μ’λ€. | ||
|
||
### μ€λ λ μμ μ± μμ€ λ¬Έμν | ||
- ν΄λμ€μ μ€λ λ μμ μ±μ λ³΄ν΅ ν΄λμ€μ λ¬Έμν μ£Όμμ κΈ°μ¬νμ§λ§, λ νΉν νΉμ±μ λ©μλλΌλ©΄ ν΄λΉ λ©μλμ μ£Όμμ κΈ°μ¬νλ€ | ||
- μ΄κ±° νμ μ κ΅³μ§ λΆλ³μ΄λΌκ³ μ°μ§ μμλ λλ€ | ||
- λ°ν νμ λ§μΌλ‘ λͺ νν μ μ μλ μ μ ν©ν°λ¦¬λΌλ©΄ μμ μ΄ λ°ννλ κ°μ²΄μ μ€λ λ μμ μ±μ λ°λμ λ¬Έμν ν΄μΌνλ€ | ||
- μ‘°κ±΄λΆ μ€λ λ μμ ν ν΄λμ€λ μ£Όμν΄μ λ¬Έμνν΄μΌ νλ€. μ΄λ€ μμλ‘ νΈμΆν λ μλΆ λκΈ°νκ° νμνμ§, κ·Έλ¦¬κ³ κ·Έ μμλ‘ νΈμΆνλ €λ©΄ μ΄λ€ λ½ νΉμ (λλ¬Όκ²) λ½λ€μ μ»μ΄μΌ νλμ§ μλ €μ€μΌ νλ€. μΌλ°μ μΌλ‘ μΈμ€ν΄μ€ μ체λ₯Ό λ½μΌλ‘ μ»μ§λ§ μμΈλ μλ€. | ||
|
||
```java | ||
// Collections.synchronizedMap API μμ | ||
synchornizedMapμ΄ λ°νν 맡μ 컬λ μ λ·°λ₯Ό μννλ €λ©΄ λ°λμ κ·Έ 맡μ λ½μΌλ‘ μ¬μ©ν΄ μλμΌλ‘ λκΈ°ννλΌ. | ||
|
||
Map<K, V> m = Collections.synchronizedMap(new HashMap<>()); | ||
Set<K> s = m.keySet(); // λκΈ°ν λΆλ‘ λ°μ μμ΄λ λλ€. | ||
|
||
synchronized(m) { // sκ° μλ mμ μ¬μ©ν΄ λκΈ°ν ν΄μΌνλ€! | ||
for (K key : s) | ||
key.f(); | ||
} | ||
``` | ||
|
||
### κ³΅κ° λ½ | ||
|
||
- ν΄λμ€κ° μΈλΆμμ μ¬μ©ν μ μλ λ½μ μ 곡νλ©΄ ν΄λΌμ΄μΈνΈμμ μΌλ ¨μ λ©μλ νΈμΆμ μμμ μΌλ‘ μν κ°λ₯ | ||
- λ΄λΆμμ μ²λ¦¬νλ κ³ μ±λ₯ λμμ± μ μ΄ λ©ν°λμ¦κ³Ό νΌμ©ν μ μμ(ex. ConcurrentHashMap) | ||
- ν΄λΌμ΄μΈνΈκ° 곡κ°λ λ½μ μ€λ μ₯κ³ λμ§ μλ μλΉμ€ κ±°λΆ κ³΅κ²©(denial-of-service attack)μ μνν μλ μλ€ | ||
- μλΉμ€ κ±°λΆ κ³΅κ²©μ λ§κΈ° μν΄μ synchronized λ©μλ λμ λΉκ³΅κ° λ½ κ°μ²΄λ₯Ό μ¬μ©ν μ μλ€ | ||
|
||
```java | ||
private final Object lock = new Object(); | ||
|
||
public void foo() { | ||
synchronized(lock) { | ||
... | ||
} | ||
} | ||
``` | ||
β λΉκ³΅κ° λ½ κ°μ²΄λ ν΄λμ€ λ°κΉ₯μμ λ³Ό μ μμΌλ ν΄λΌμ΄μΈνΈκ° κ·Έ κ°μ²΄μ λκΈ°νμ κ΄μ¬ν μ μλ€ | ||
(λ½ κ°μ²΄λ₯Ό λκΈ°ν λμ κ°μ²΄ μμΌλ‘ μΊ‘μν) | ||
β λΉκ³΅κ° λ½ κ°μ²΄ κ΄μ©κ΅¬λ 무쑰건 μ€λ λ μμ ν΄λμ€μμλ§ μ¬μ©ν μ μλ€ | ||
β μμμ©μΌλ‘ μ€κ³ν ν΄λμ€μ νΉν μ λ§λλ€ | ||
(μμμ© ν΄λμ€μμ μμ μ μΈμ€ν΄μ€λ₯Ό λ½μΌλ‘ μ¬μ©νλ€λ©΄, νμ ν΄λμ€λ μμ£Ό μ½κ² μλμΉμκ² κΈ°λ° ν΄λμ€μ λμμ λ°©ν΄ν μ μλ€) | ||
|
||
### μ 리 | ||
λͺ¨λ ν΄λμ€κ° μμ μ μ€λ λ μμ μ± μ 보λ₯Ό λͺ νν λ¬Έμν ν΄μΌ νλ€. μ νν μΈμ΄λ‘ μ νν μ€λͺ νκ±°λ μ€λ λ μμ μ± μ λν μ΄μ μ μ¬μ©ν μ μλ€. synchronized νμ μλ λ¬Έμνμ κ΄λ ¨μ΄ μλ€. μ‘°κ±΄λΆ μ€λ λ μμ ν΄λμ€λ λ©μλλ₯Ό μ΄λ€ μμλ‘ νΈμΆν λ μΈλΆ λκΈ°νκ° μꡬλκ³ , κ·Έλ μ΄λ€ λ½μ μ»μ΄μΌ νλμ§λ μλ €μ€μΌ νλ€. 무쑰건μ μ€λ λ μμ ν΄λμ€λ₯Ό μμ±ν λλ synchronized λ©μλκ° μλ λΉκ³΅κ° λ½ κ°μ²΄λ₯Ό μ¬μ©νμ. μ΄λ κ² ν΄μΌ ν΄λΌμ΄μΈνΈλ νμ ν΄λμ€μμ λκΈ°ν λ©μ»€λμ¦μ κΉ¨λ¨λ¦¬λ κ±Έ μλ°©ν μ μκ³ , νμνλ€λ λμμ λ μ κ΅ν λμμ± μ μ΄ λ©μ»€λμ¦μΌλ‘ μ¬κ΅¬νν μ¬μ§κ° μκΈ΄λ€. |