์๋ก
๋ฉํฐ ์ค๋ ๋๋ฅผ ํ์ฉํ ์๋น์ค ๊ฐ๋ฐ์ ํ๋ ์ค, ํด๋น ๊ฐ๋ ์ ์๊ฒ ๋์๊ณ ์ด๊ฒ ๋ฌด์์ธ์ง์ ๋ํด ์์ธํ๊ฒ ๋ค๋ฃฐ ํ์๊ฐ ์๋ค๊ณ ์๊ฐํด ์์ฑํ๋ค.
์ ์
ConcurrentHashMap
์ Java์์ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ค๊ณ๋ ์ค๋ ๋ ์์ ํ HashMap์ด๋ค.
Java 1.5๋ถํฐ java.util.concurrent ํจํค์ง์ ํฌํจ๋์ด ์์ผ๋ฉฐ, ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์ฝ๊ณ ์ธ ์ ์๋๋ก ํน๋ณํ ๋ฝ ๋ถํ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํ๋ค.
๋ง๋ค์ด์ง ๋ฐฐ๊ฒฝ
- ๊ธฐ์กด HashMap์ ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ๋๊ธฐํ๊ฐ ๋์ด ์์ง ์์
race condition
์ด ๋ฐ์ํ ์ ์์ - ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด
Hashtable
์ด๋synchronizedMap
์ ์ฌ์ฉํ์ง๋ง, ์ด๋ค์ ์ ์ฒด ๋งต์ ๋ํด synchronized ์ฒ๋ฆฌ๋ฅผ ํ์ฌ ์ฑ๋ฅ ๋ณ๋ชฉ์ด ์๊น.
=> ์ด๋ฅผ ๊ฐ์ ํ๊ณ ์ ๋ณด๋ค ์ ๊ตํ๊ฒ ๋๊ธฐํ๋ฅผ ์ ์ดํ ์ ์๋ ConcurrentHashMap
์ด ๋ฑ์ฅํ์๋ค.
race condition
: ๋ ์ด์์ ์ค๋ ๋๊ฐ ๋์์ ๊ฐ์ ์์์ ์ ๊ทผํ๊ฑฐ๋ ๋ณ๊ฒฝํ๋ฉด์, ์คํ ์์์ ๋ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋ผ์ง๋ ๋ฌธ์ ์ํฉ
ํน์ง
- ์ธ๋ถํ๋ ๋ฝ(๋ถํ ๋ฝ):
Java 8 ์ด์ ๊น์ง๋ Segment ๋จ์๋ก ๋ฝ์ ๋๋ด๊ณ , Java 8๋ถํฐ๋ bucket(๋ฐฐ์ด์ ๊ฐ ์์) ๋จ์๋ก ๋๊ธฐํํ์ฌ ๋ณ๋ ฌ์ฑ์ ๋์๋ค. - ์ฝ๊ธฐ ์์ ์ ๋ฝ ์์ด ์ฒ๋ฆฌ
- ๋๋ถ๋ถ์ ์ฝ๊ธฐ ์์ ์ ๋ฝ ์์ด ์งํ๋๋ฉฐ, ๋ณ๊ฒฝ ์์ ๋ง ์ต์ํ์ ๋ฝ์ผ๋ก ์ฒ๋ฆฌ๋๋ค.
- null key, null value ๊ธ์ง
- null ํค๋ null ๊ฐ์ ํ์ฉํ์ง ์์ผ๋ฉฐ, NullPointerException์ด ๋ฐ์ํ๋ค.
- ์ฑ๋ฅ ์ค์ฌ ์ค๊ณ
- ๋ฝ์ ๋ฒ์๋ฅผ ์ต์ํํ์ฌ ์ฑ๋ฅ ์ ํ ์์ด ์ค๋ ๋ ์์ ์ฑ์ ํ๋ณดํ๋ค.
๋์ ๊ตฌ์กฐ
1. ๋ฒํท์ด ๋น์ด ์์ผ๋ฉด ๋ฝ ์์ด ๋ฃ๋๋ค (CAS)
- ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ ์์น(๋ฒํท)๊ฐ ๋น์ด ์์ผ๋ฉด,
- ๋ณต์กํ ๋ฝ ์์ด, ํ ๋ฒ์ ๋ฃ์ ์ ์๋ ๋ฐฉ๋ฒ(CAS)์ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ฝ์
CAS(Compare-And-Swap): "ํ์ฌ ๊ฐ์ด ์์ํ ๊ฐ๊ณผ ๊ฐ์ผ๋ฉด ์๋ก์ด ๊ฐ์ผ๋ก ๋ฐ๊ฟ๋ผ!" ๋ผ๋ ์กฐ๊ฑด๋ถ ์ฐ์ฐ
// Java์ AtomicInteger์์ ์์
AtomicInteger count = new AtomicInteger(0);
count.compareAndSet(0, 1); // ํ์ฌ ๊ฐ์ด 0์ด๋ฉด 1๋ก ๋ฐ๊ฟ๋ผ`
2. ์ถฉ๋ํ๋ฉด ๊ทธ ๋ฒํท๋ง ์ ๊ทผ๋ค (synchronized)
- ๊ฐ์ ๋ฒํท์ ์ฌ๋ฌ ๋ฐ์ดํฐ๊ฐ ๋ค์ด๊ฐ์ผ ํ ๋(ํด์ ์ถฉ๋),
- ์ ์ฒด ๋งต์ ์ ๊ทธ์ง ์๊ณ ๊ทธ ๋ฒํท ํ๋๋ง ์ ๊ทผ๋ค.
- ํด๋น ๋ฐฉ๋ฒ์ผ๋ก ๋ณ๋ ฌ ์ฒ๋ฆฌ ์ฑ๋ฅ ์ ์ง
3. ์ถฉ๋์ด ๋ง์์ง๋ฉด ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ฅผ ํธ๋ฆฌ๋ก ๋ฐ๊พผ๋ค
- ๊ฐ์ ๋ฒํท์ ๋ฐ์ดํฐ๊ฐ ๋๋ฌด ๋ง์ด ๋ชฐ๋ฆฌ๋ฉด
- ๋จ์ํ ์ค ์ธ์ฐ๋ ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ณด๋ค, ๊ฒ์ ๋น ๋ฅธ ํธ๋ฆฌ(Red-Black Tree)๋ก ๋ฐ๊ฟ์
- ์ฑ๋ฅ ์ ํ๋ฅผ ๋ง๋๋ค.
์ฅ์ ๊ณผ ๋จ์
์ฅ์
- ๋์ ๋์์ฑ ์ฒ๋ฆฌ: ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์ฝ๊ธฐ/์ฐ๊ธฐ ๊ฐ๋ฅ
- Deadlock ๋ฐฉ์ง: ์ ์ฒด ๋งต์ ์ ๊ทธ์ง ์๊ธฐ ๋๋ฌธ์ ๋ณ๋ชฉ์ด ์ ์
- ์ ๋ขฐ์ฑ ์๋ ๋์ ์ฒ๋ฆฌ: ๋ฝ์ด ์ธ๋ถํ๋์ด ์์ด race condition ๋ฐฉ์ง์ ํจ๊ณผ์
๋จ์
- null ํค/๊ฐ ๋ถ๊ฐ: ๊ธฐ์กด HashMap๊ณผ ๋ฌ๋ฆฌ null ๊ด๋ จ ์ ์ฐ์ฑ์ด ์์
- ๋ณต์กํ ๋ด๋ถ ๊ตฌํ: ๊ตฌ์กฐ๊ฐ ๋ณต์กํด ๋๋ฒ๊น ์ด๋ ์ปค์คํฐ๋ง์ด์ง์ด ์ด๋ ค์
- ํน์ ์ํฉ์์์ ์ฑ๋ฅ ์ ํ: ๋์ ์ถฉ๋๋ฅ ์ segment ๊ฐ contention ๋ฐ์ ๊ฐ๋ฅ
contention
(๋ฝ ๊ฒฝ์, ๊ฒฝํฉ): ์ฌ๋ฌ ์ค๋ ๋๊ฐ ํ๊ฐ ๋ฒํท์ ์ ๊ทผํ ๋ ๋ฒํท์ ๋ฝ์ด ๋ณ๋ชฉ ์ง์ ์ด ๋ผ์ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋๊ธฐ ์ํ์ ๋น ์ง๋ ์ํฉ
๐ธ ๋์์ฑ ์ฒ๋ฆฌ ๋น๊ต
์ปฌ๋ ์ | ์ค๋ ๋ ์์ ์ฑ | ์ฑ๋ฅ | ๋น๊ณ |
---|---|---|---|
HashMap | X | ๋น ๋ฆ | ๋๊ธฐํ ๋ถ๊ฐ |
Hashtable | O | ๋๋ฆผ | ์ ์ฒด ๋ฉ์๋ ๋๊ธฐํ |
Collections.synchronizedMap() | O | ๋ณดํต | ๋จ์ผ ๋ฝ ๊ธฐ๋ฐ |
ConcurrentHashMap | O | ๊ฐ์ฅ ๋น ๋ฆ | ์ธ๋ถํ๋ ๋ฝ, ๋ณ๋ ฌ์ฑ ์ฐ์ |
'Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[JAVA] GC - JAVA ๋ฒ์ ๋ณ ์ฃผ์ ์๊ณ ๋ฆฌ์ฆ (0) | 2025.05.17 |
---|---|
[JAVA] GC - Mark & Sweep ๋์ ์๋ฆฌ (0) | 2025.05.17 |
[JAVA] File I/O (0) | 2024.07.28 |
[JAVA] Exception (0) | 2024.07.28 |
[JAVA] Stream API (0) | 2024.07.25 |