๋™์‹œ์„ฑ, BlockingQueues(Java 7) - 1

"์•ˆ๋…•, ์•„๋ฏธ๊ณ !"

"์•ˆ๋…•, ๊น€!"

"์˜ค๋Š˜์€ ๋™์‹œ์„ฑ์— ๋Œ€ํ•ด ๋ง์”€๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค."

" ๋™์‹œ์„ฑ์€ ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ์ž‘์—…์— ์ตœ์ ํ™”๋œ ํŠน์ˆ˜ ํด๋ž˜์Šค๋ฅผ ํฌํ•จํ•˜๋Š” Java ํด๋ž˜์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋งค์šฐ ํฅ๋ฏธ๋กญ๊ณ  ๊ด‘๋ฒ”์œ„ํ•œ ์ฃผ์ œ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์˜ค๋Š˜์€ ์†Œ๊ฐœ๋งŒ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ํŒจํ‚ค์ง€ ์ด๋ฆ„์€ java.util์ž…๋‹ˆ๋‹ค. ๋™์‹œ์„ฑ ํŒจํ‚ค์ง€์ž…๋‹ˆ๋‹ค. ๋ช‡ ๊ฐ€์ง€ ํฅ๋ฏธ๋กœ์šด ํด๋ž˜์Šค์— ๋Œ€ํ•ด ๋ง์”€๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค."

" ์›์ž ์œ ํ˜•. "

"count++๋„ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•œ ์ž‘์—…์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์„ ์ด๋ฏธ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ€์ˆ˜๊ฐ€ 1์”ฉ ์ฆ๊ฐ€ํ•˜๋ฉด ์‹ค์ œ๋กœ ์„ธ ๊ฐ€์ง€ ์ž‘์—…์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ณ€์ˆ˜๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค."

"๊ทธ๋ž˜, Ellie๋Š” ์–ผ๋งˆ ์ „์— ๋‚˜์—๊ฒŒ ๋งํ–ˆ๋‹ค."

์Šค๋ ˆ๋“œ 1 ์Šค๋ ˆ๋“œ 2 ๊ฒฐ๊ณผ
register1 = count;
register1++;
count = register1;
register2 = count;
register2++;
count = register2;
register1 = count;
register2 = count;
register2++;
count = register2;
register1++;
count = register1;

"์ •ํ™•ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ Java๋Š” ์ด๋Ÿฌํ•œ ์ž‘์—…์„ ํ•˜๋‚˜๋กœ, ์ฆ‰ ์›์ž์ ์œผ๋กœ(์›์ž๋Š” ๋‚˜๋ˆŒ ์ˆ˜ ์—†์Œ) ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ ์œ ํ˜•์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค."

"์˜ˆ๋ฅผ ๋“ค์–ด Java์—๋Š” AtomicInteger, AtomicBoolean, AtomicDouble ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค."

"<์นด์šดํ„ฐ> ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค."

์˜ˆ
class Counter
{
 private int c = 0;

 public void increment()
 {
  c++;
 }

 public void decrement()
 {
  c--;
 }

 public int value()
 {
  return c;
 }
}

"์ด ํด๋ž˜์Šค์˜ ๊ฐœ์ฒด๋ฅผ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ค๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?"

"์Œ, ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋ฅผ ๋™๊ธฐํ™”ํ•˜๊ณ  ์™„๋ฃŒํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค."

์˜ˆ
class synchronized Counter
{
 private int c = 0;

 public synchronized void increment()
 {
  c++;
 }

 public synchronized void decrement()
 {
  c--;
 }

 public synchronized int value()
 {
  return c;
 }
}

"์ž˜ํ–ˆ์–ด. ํ•˜์ง€๋งŒ ์›์ž ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ๋ชจ์Šต์ผ๊นŒ?"

์˜ˆ
class AtomicCounter
{
 private AtomicInteger c = new AtomicInteger(0);

 public void increment()
 {
  c.incrementAndGet();
 }

 public void decrement()
 {
  c.decrementAndGet();
 }

 public int value()
 {
  return c.get();
 }
}

"๊ท€ํ•˜์˜ ํด๋ž˜์Šค์™€ ๋‚ด ํด๋ž˜์Šค๋Š” ๋ชจ๋‘ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜์ง€๋งŒ AtomicInteger๊ฐ€ ์žˆ๋Š” ํด๋ž˜์Šค๊ฐ€ ๋” ๋น ๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค."

"์Œ, ์•ฝ๊ฐ„์˜ ์ฐจ์ด์ธ๊ฐ€์š”?"

"์˜ˆ. ์ œ ๊ฒฝํ—˜์— ๋น„์ถ”์–ด ๋ณผ ๋•Œ ์ €๋Š” ํ•ญ์ƒ ๋™๊ธฐํ™”๋กœ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๊ฐ€ ์ž‘์„ฑ๋˜๊ณ  ์ตœ์ ํ™” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹œ์ž‘๋œ ํ›„์—์•ผ ์›์ž ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•˜๊ธฐ ์‹œ์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์–ด์จŒ๋“  ๋‚˜๋Š” ๋‹น์‹ ์„ ์›ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌํ•œ ์œ ํ˜•์ด ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ธฐ ์œ„ํ•ด์„œ์ž…๋‹ˆ๋‹ค. ์ ๊ทน์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋”๋ผ๋„ ์ด๋Ÿฌํ•œ ์œ ํ˜•์ด ์‚ฌ์šฉ๋˜๋Š” ์ฝ”๋“œ์— ๋ถ€๋”ชํž ๊ฐ€๋Šฅ์„ฑ์ด ํ•ญ์ƒ ์žˆ์Šต๋‹ˆ๋‹ค."

"๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋ง์ด ๋ฉ๋‹ˆ๋‹ค."

"๊ทธ๋Ÿฐ๋ฐ ์›์ž ์œ ํ˜•์ด ๋ถˆ๋ณ€์ด ์•„๋‹ˆ๋ผ๋Š” ์‚ฌ์‹ค์„ ์•Œ๊ณ  ๊ณ„์…จ์Šต๋‹ˆ๊นŒ? ํ‘œ์ค€ Integer ํด๋ž˜์Šค ์™€ ๋‹ฌ๋ฆฌ AtomicInteger ์—๋Š” ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค."

"์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. String ๋ฐ StringBuffer ์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค ."

"์˜ˆ, ๊ทธ๋Ÿฐ ๊ฒƒ์ž…๋‹ˆ๋‹ค."

" ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•œ ์ปฌ๋ ‰์…˜. "

"์ด๋Ÿฌํ•œ ์ปฌ๋ ‰์…˜์˜ ์˜ˆ๋กœ ConcurrentHashMap์„ ์ œ์‹œํ•ด๋„ ๋ฉ๋‹ˆ๊นŒ? HashMap์„ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ค๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?"

"๋ชจ๋“  ๋ฉ”์„œ๋“œ๋ฅผ ๋™๊ธฐํ™”ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?"

"๋ฌผ๋ก ์ด์ฃ . ํ•˜์ง€๋งŒ ์ด์ œ ๊ทธ๋Ÿฌํ•œ SynchronizedHashMap์ด ํ•˜๋‚˜ ์žˆ๊ณ  ์—ฌ๊ธฐ์— ์•ก์„ธ์Šคํ•˜๋Š” ์ˆ˜์‹ญ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด ๋ณด์„ธ์š”. ๊ทธ๋ฆฌ๊ณ  ์ดˆ๋‹น 100๋ฒˆ์”ฉ ์ƒˆ ํ•ญ๋ชฉ์ด ๋งต์— ์ถ”๊ฐ€๋˜๊ณ  ๊ทธ ๊ณผ์ •์—์„œ ์ „์ฒด ๊ฐœ์ฒด๊ฐ€ ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ๋ฅผ ์œ„ํ•ด ์ž ๊น๋‹ˆ๋‹ค."

"์Œ, ์ด๊ฒƒ์ด ํ‘œ์ค€ ์ ‘๊ทผ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?"

"Java์˜ ์ œ์ž‘์ž๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฉ‹์ง„ ๊ฒƒ์„ ์ƒ๊ฐํ•ด ๋ƒˆ์Šต๋‹ˆ๋‹ค."

"์šฐ์„  ํ•˜๋‚˜์˜ ๋ธ”๋ก์— ConcurrentHashMap์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜์ง€๋งŒ '๋ฒ„ํ‚ท'์ด๋ผ๋Š” ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ•๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ˆ„๊ตฐ๊ฐ€ ConcurrentHashMap์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์ „์ฒด ๊ฐœ์ฒด๊ฐ€ ์•„๋‹Œ ์•ก์„ธ์Šค๋˜๋Š” ๋ฒ„ํ‚ท๋งŒ ์ž ๊ธ‰๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ฆ‰, ๋งŽ์€ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐœ์ฒด๋ฅผ ๋™์‹œ์— ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค."

"๋‘ ๋ฒˆ์งธ๋กœ, ๋ชฉ๋ก/์ง€๋„์˜ ์š”์†Œ๋ฅผ ๋ฐ˜๋ณตํ•˜๋ฉด์„œ ๋™์‹œ์— ๋ชฉ๋ก์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•˜์‹ญ๋‹ˆ๊นŒ? ์ด๋Ÿฌํ•œ ์ฝ”๋“œ๋Š” ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค."

๋ฃจํ”„์—์„œ ์ปฌ๋ ‰์…˜์˜ ์š”์†Œ๋ฅผ ๋ฐ˜๋ณตํ•˜๋ฉด์„œ ๋™์‹œ์— ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”.
HashMap<String, Integer> map = new HashMap<String, Integer>();

for (String key: map.keySet())
{
 if (map.get(key) == 0)
  map.remove(key);
}

"ํ•˜์ง€๋งŒ ConcurrentHashMap์—์„œ๋Š” ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค."

๋ฃจํ”„์—์„œ ์ปฌ๋ ‰์…˜์˜ ์š”์†Œ๋ฅผ ๋ฐ˜๋ณตํ•˜๋ฉด์„œ ๋™์‹œ์— ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค."
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();

for (String key: map.keySet())
{
 if (map.get(key) == 0)
  map.remove(key);
}

"๋™์‹œ ํŒจํ‚ค์ง€์—๋Š” ๋งŽ์€ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ด๋Ÿฌํ•œ ํด๋ž˜์Šค๋ฅผ ์•„์ฃผ ์ž˜ ์ดํ•ดํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค."

"๊ทธ๋ ‡๊ตฐ์š”. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. Kim. ์ •๋ง ํฅ๋ฏธ๋กœ์šด ์ˆ˜์—…์ž…๋‹ˆ๋‹ค. ์–ธ์  ๊ฐ€๋Š” ๊ฑฐ์žฅ์ฒ˜๋Ÿผ ๋งˆ์Šคํ„ฐํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค."