Å×Å©´ÏÄà Ä÷³-ÀÚ¹Ù
ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨°ú ¾²·¹µå
ÀÚ¹Ù°¡ ¾ð¾î Â÷¿ø¿¡¼ äÅÃÇÑ ´ÙÁß ¾²·¹µå ±â´ÉÀº Ãʱâ ÀÚ¹ÙÀÇ È®»ê¿¡ Å©°Ô ±â¿©ÇÏ´Â ¿äÀÎÀ̾ú´Ù. ¾ð¾î Â÷¿ø¿¡¼ ¾²·¹µå¸¦ ½±°Ô »ý¼ºÇÏ°í °£´ÜÇÏ°Ô µ¿±âȸ¦ »ç¿ëÇÒ ¼ö ÀÖ´Â ±â´ÉÀ» Á¦°øÇϱ⠶§¹®¿¡ ´ÙÁß ¾²·¹µå´Â ÀÚ¹Ù ÇÁ·Î±×·¥ÀÇ ±âº» ¿ä±¸ »çÇ×ó·³ µÇ¾ú´Ù. ÇÏÁö¸¸, ¸ÖƼ ÇÁ·Î¼¼¼¸¦ ÀåÂøÇÑ ÄÄÇ»Å͵éÀÇ È®»ê°ú ´õºÒ¾î ´ÙÁß ¾²·¹µå¸¦ »ç¿ëÇÑ ÇÁ·Î±×·¥¿¡¼ ¿¹±âÄ¡ ¸øÇÑ µ¥µå¶ô »óȲÀÌ Á¾Á¾ ¹ß»ýÇÏ°í ÇÁ·Î±×·¡¸ÓµéÀº À̸¦ Á¦´ë·Î ÇØ°áÇÏÁö ¸øÇÏ´Â °æ¿ì°¡ ¸¹´Ù.
¿©±â¿¡¼´Â ÀÚ¹ÙÀÇ ´ÙÁß ¾²·¹µå ȯ°æ¿¡¼ ¹ß»ýÇÏ´Â ¸î °¡Áö ÀüÁ¦µé°ú ÀÚ¹Ù ¾ð¾î¿¡¼ Á¤ÀÇÇÏ°í ÀÖ´Â ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨, ±×¸®°í À߸øµÈ µ¿±âÈ ±¸Á¶ÀÇ ³²¿ëÀ» ÇÇÇÏ°í ¹®¸ÆÀÌ ¿ä±¸ÇÏ´Â ÀûÀýÇÑ ±¸Á¶¸¦ »ç¿ëÇÏ´Â µ¥ Å« µµ¿òÀ» ÁÙ ÀÚ¹Ù 2 SDK 1.5ÀÇ »õ·Î¿î ¾²·¹µå µ¿±âÈ °ü·Ã ±¸Á¶µéÀ» ¼Ò°³ÇÏ°íÀÚ ÇÑ´Ù.
À±°æ±¸ yoonforh at gmail dot com
Ƽ¸Æ½º¼ÒÇÁÆ® ±â¼ú¿¬±¸¼Ò¿¡¼ BPM ÆÀÀ» À̲ø°í ÀÖ´Ù. ÀÌÀü¿¡´Â ÀÚ¹Ù ¿öµå ÇÁ·Î¼¼¼ °³¹ß, PCS HLR ½Ã½ºÅÛ °³¹ß µî¿¡ Âü¿©Çß´Ù. ±¹³» ÃÖÃÊ·Î ÀÚ¹Ù À¥ °Ô½ÃÆÇÀÎ ÀÚ¹Ù ¹¯°í ´äÇϱ⠰ԽÃÆÇÀ» ¿î¿µÇßÀ¸¸ç(1997), ÀÔ¹®¼ÀÎ Áö³ª¿Í ÇÔ²² ÇÏ´Â ÀÚ¹Ù 2(1999), º»°ÝÀûÀÎ ÀÚ¹Ù °³¹ßÀÚ¸¦ À§ÇÑ µÎ²¨¿î Ã¥ÀÎ ÀÚ¹Ù 2 SDK 1.4 ½ÃÀÛ ±×¸®°í ¿Ï¼º(2003) µîÀÇ Ã¥À» ÁýÇÊÇß´Ù. ±×¿Ü, ÇÁ·Î±×·¥ ¼¼°è ƯÁý ¾ÖÇø´ÀÇ Çâ±â(1996), ¸¶¼Ò ÁִϾî ÀÚ¹Ù À̾߱â(1999) µî ¿©·¯ Â÷·Ê ÀÚ¹Ù °ü·Ã ±â»ç¸¦ ±â°íÇÏ¿´´Ù. ±¹³» ¼ÒÇÁÆ®¿þ¾î »ê¾÷ÀÇ ¾î·Á¿î Çö½Ç ¼Ó¿¡¼ ¿À·¡µµ·Ï ÄÚ´õ·Î ³²°í ½Í´Ù´Â ¼Ò¹ÚÇÑ Èñ¸ÁÀ» °¡Áö°í ÀÖ´Ù.
°¡À̵å
¿î¿µÃ¼Á¦ | ÀÚ¹Ù 2 SDK 1.5ÆÇ ½ÇÇà °¡´É ȯ°æ
°³¹ßµµ±¸ | ÀÚ¹Ù 2 SDK 1.5ÆÇ
±âº»Áö½Ä | ÀÚ¹Ù 2 SDK 1.4ÆÇ, ¾²·¹µå¿Í µ¿±âÈ
´ÙÁß ¾²·¹µå ȯ°æ¿¡¼ °æÀï Á¶°Ç°ú µ¥µå¶ôÀº ÇÇÇÒ ¼ö ¾ø´Â °ü°èÀÌ´Ù. ¿©·¯ °³ÀÇ ¾²·¹µå°¡ µ¿½Ã¿¡ µ¿ÀÏÇÑ º¯¼ö, °´Ã¼ ȤÀº ÀÚ¿øÀ» Â÷ÁöÇÏ·Á°í ÇÏ´Â °æ¿ì °æÀï Á¶°ÇÀÌ ¹ß»ýÇϸç, °æÀï Á¶°Ç¿¡¼ ÇÑ ¾²·¹µåÀÇ ¹èŸÀû ¸®¼Ò½º Á¡À¯¸¦ º¸ÀåÇÏ´Â ¹æ¹ýÀ¸·Î µ¿±âȸ¦ »ç¿ëÇÏ°Ô µÈ´Ù. µ¿±âȸ¦ À߸ø ó¸®ÇÏ´Â °æ¿ì ¾î´À ¾²·¹µåµµ ÁøÇàµÇÁö ¸øÇÏ´Â ±³Âø »óÅ Áï, µ¥µå¶ô¿¡ ºüÁö°Ô µÇ´Âµ¥, Á¶±Ý º¹ÀâÇÑ ¾²·¹µå ±¸Á¶¸¦ ´Ù·ç´Ù º¸¸é Á¾Á¾ °ñ¸Ó¸®¸¦ ¾Î°Ô µÇ´Â ¹®Á¦ÀÏ °ÍÀÌ´Ù.
ÃÖ±Ù µé¾î, ¿©·¯ °³ÀÇ CPU¸¦ ÀåÂøÇÑ ÄÄÇ»Æà ȯ°æÀÌ ÀϹÝÈµÇ¸é¼ ÇϳªÀÇ CPU¿¡¼´Â ¹®Á¦ ¾øÀÌ ½ÇÇàµÇ´ø ÇÁ·Î±×·¥µéÀÌ µ¥µå¶ô°ú °°Àº ¿À·ù¸¦ º¸ÀÌ´Â °æ¿ìµµ Á¾Á¾ ¹ß°ßµÈ´Ù. ÇϳªÀÇ CPU¿¡¼´Â ¾²·¹µå °£ÀÇ ÁøÁ¤ÇÑ µ¿½Ã¼ºÀÌ ¾øÀ¸¹Ç·Î °æÀï Á¶°ÇÀÌ µ¥µå¶ôÀ¸·Î ¹ßÀüÇÏÁö ¾Ê°Å³ª È®·üÀÌ ¾ÆÁÖ ³·¾ÒÁö¸¸, ´ÙÁß CPU ȯ°æ¿¡¼´Â ¿©·¯ °³ÀÇ ¾²·¹µå°¡ ±×¾ß¸»·Î µ¿½Ã¿¡ ÀÚ¿ø¿¡ Á¢±ÙÇÏ´Â °æ¿ì°¡ ÀæÀ¸¹Ç·Î, °¨ÃçÁá´ø ¹®Á¦µéÀÌ ¹ß°ßµÇ´Â °ÍÀÌ´Ù.
À̹ø È£¿¡¼´Â ¾²·¹µåÀÇ µ¿½Ã¼º ¹®Á¦¿¡ °ü·ÃµÈ Á¶±Ý º¹ÀâÇÑ À̽´µéÀ» ´Ù·ç°í, µ¿½Ã¼º ¹®Á¦¸¦ ÇØ°áÇϱâ À§ÇÑ Àß Á¤ÀÇµÈ ±¸Á¶µé, ƯÈ÷ ÀÚ¹Ù 2 SDK 1.5¿¡ »õ·Î Æ÷ÇԵǴ java.util.concurrent ÆÐÅ°Áö¿¡ ´ëÇØ ¼Ò°³ÇÑ´Ù.
µ¿±âÈ
°æÀï Á¶°Ç
¿©·¯ °³ÀÇ ¾²·¹µå°¡ µ¿½Ã¿¡ ½ÇÇàµÇ´Â °æ¿ì, ¿î¿µ üÁ¦ÀÇ ½ºÄÉÁÙ¸µ Á¤Ã¥°ú ½ÇÇà ȯ°æ¿¡ µû¶ó ¾²·¹µåÀÇ ½ÇÇà ¼ø¼°¡ º¯°æµÇ¹Ç·Î ¿øÇÏÁö ¾Ê´Â °á°ú¸¦ ³º´Â °æ¿ì°¡ ¹ß»ýÇÑ´Ù.
ÇÁ·Î¼¼½º ´ÜÀ§¿¡¼ °ü¸®µÇ´Â ¸®¼Ò½ºÀÇ °æ¿ì °¢ ¾²·¹µå´Â Ç×»ó ¸®¼Ò½º¿¡ ´ëÇØ °æÀïÇÏ°Ô µÈ´Ù. ÇϳªÀÇ ÆÄÀÏÀ» ¿¾î ÀÔ·Â ½ºÆ®¸²À» ¸¸µç ´ÙÀ½ µÎ °³ÀÇ ¾²·¹µå¿¡¼ µ¿½Ã¿¡ ÀоîµéÀδٸé, ¾î´À ¾²·¹µå°¡ ¾î´À ºÎºÐÀ» ÀÐ°Ô µÉÁö ¾Ë ¼ö ¾ø´Ù.
¸®¼Ò½º°¡ ¾Æ´Ï¶ó°í ÇÏ´õ¶óµµ ÇÁ·Î±×·¥ ³»¿¡¼ µÎ °³ÀÇ ¾²·¹µå°¡ °øÀ¯ÇÏ´Â º¯¼ö³ª °´Ã¼¿¡ ´ëÇؼµµ °æÀïÀº ¾ðÁ¦µçÁö ¹ß»ýÇÒ ¼ö ÀÖ´Ù. ´ÙÀ½ »óȲÀ» »ý°¢Çغ¸ÀÚ.
? ¾²·¹µå T1°ú T2°¡ µ¿½Ã¿¡ ½ÇÇàµÇ¸ç µÑ ´Ù value¶ó´Â Á¤¼ö°ª¿¡ ´ëÇØ ÂüÁ¶¸¦ °¡Áö°í ÀÖ´Ù.
? T1Àº value¿¡ 5¸¦ ´õÇÏ´Â ¿¬»êÀ» ¼öÇàÇϸç T2´Â value¿¡ 5¸¦ °öÇÏ´Â ¿¬»êÀ» ¼öÇàÇÑ´Ù.
Ãʱâ value °ªÀÌ 0À̾ú´Ù¸é °á°ú´Â ¾î¶»°Ô µÉ±î? T1°ú T2ÀÇ ¾î´À »ê¼ú ¿¬»êÀÌ ¸ÕÀú ½ºÄÉÁÙ¸µµÇ´À³Ä¿¡ µû¶ó (0 + 5) * 5 = 25°¡ µÉ ¼öµµ ÀÖ°í (0 * 5) + 5 = 5°¡ µÉ ¼öµµ ÀÖ´Ù.
ÀÌ·¸°Ô ¿©·¯ °³ÀÇ ¾²·¹µå°¡ ½ºÄÉÁÙ¸µµÇ´Â ¼ø¼¿¡ µû¶ó °á°ú°¡ º¯ÇÒ ¼ö ÀÖ´Â »óȲÀ» °æÀï Á¶°Ç(race condition)À̶ó°í ºÎ¸¥´Ù.
<Ç¥ 1> T1ÀÌ ¸ÕÀú ½ÇÇàµÉ °æ¿ìÀÇ value °ª
T1 ¾²·¹µå |
T2 ¾²·¹µå |
value °ª |
|
|
0 (ÃʱⰪ) |
value += 5; |
|
0 + 5 = 5 |
|
value *= 5; |
5 * 5 = 25 |
<Ç¥ 2> T2°¡ ¸ÕÀú ½ÇÇàµÉ °æ¿ìÀÇ value °ª
T1 ¾²·¹µå |
T2 ¾²·¹µå |
value °ª |
|
|
0 (ÃʱⰪ) |
|
value *= 5; |
0 * 5 = 0 |
value += 5; |
|
0 + 5 = 5 |
½ÇÁ¦ÀÇ °æÀï Á¶°Ç
<Ç¥1>°ú <Ç¥2>¿¡¼ ¼³¸íÇÑ °æÀï Á¶°ÇÀº °³³äÀûÀÎ °ÍÀ¸·Î ½ÇÁ¦·Î ¹ß»ýÇÏ´Â ÀÚ¹Ù ÇÁ·Î±×·¥ÀÇ ¾²·¹µå °£ °æÀï Á¶°ÇÀº Á¶±Ý ´õ º¹ÀâÇÏ°Ô Ç¥ÇöµÉ ¼ö ÀÖ´Ù. ±× ÀÌÀ¯´Â °¢ ¾²·¹µå°¡ ¼öÇàÇÏ´Â value += 5; ȤÀº value *= 5; ¸í·ÉµéÀÌ ÀÚ¹Ù °¡»ó ¸Ó½Å ¼öÁØ¿¡¼ ¿øÀÚ¼ºÀ» º¸ÀåÇÒ ¼ö ÀÖ´Â ÀνºÆ®·°¼ÇÀÌ ¾Æ´Ï±â ¶§¹®ÀÌ´Ù.
¸ÕÀú ´ÙÀ½ ÀÚ¹Ù ÇÁ·Î±×·¥À» ½ÇÇàÇغ¸ÀÚ.
<¸®½ºÆ® 1> NotSynchronizedBlock.java ¼Ò½º ÄÚµå
public class NotSynchronizedBlock {
int value = 0;
void doit() {
// RunnableÀ» ±¸ÇöÇÏ´Â À̸§¾ø´Â ³»ºÎ Ŭ·¡½º
Runnable r = new Runnable() {
public void run() {
while (true) {
value += 5;
value -= 5;
}
}
};
new Thread(r, "T1").start(); // T1 ¾²·¹µå ½ÃÀÛ
new Thread(r, "T2").start(); // T2 ¾²·¹µå ½ÃÀÛ
// value °ªÀÌ ¹üÀ§¸¦ ³Ñ´ÂÁö °Ë»ç
while (true) {
int copy = value; // copy first
if (copy > 10 || copy < 0) {
System.out.println("value = " + copy);
}
}
}
public static void main(String[] args) {
new NotSynchronizedBlock().doit();
}
}
¿¹Á¦¿¡ µîÀåÇÏ´Â ¾²·¹µå´Â ¸ðµÎ ¼¼ °³ÀÌ´Ù. óÀ½ ÀÚ¹Ù ÇÁ·Î±×·¥ÀÌ ½ÇÇàµÉ ¶§ ½ÇÇàµÇ´Â ÁÖ ¾²·¹µå°¡ ÀÖ°í, RunnableÀ» ±¸ÇöÇÑ °´Ã¼¸¦ ÀÎÀÚ·Î ÇÏ¿© ½ÇÇàÇÏ´Â µÎ °³ÀÇ ¾²·¹µå T1, T2°¡ ÀÖ´Ù.
µÎ °³ÀÇ ¾²·¹µå´Â °¢°¢ ¹«ÇÑ ¹Ýº¹¹®À» µ¹¸é¼ ¼·Î °øÀ¯ÇÏ´Â º¯¼öÀÎ value¿¡ °æÀïÀûÀ¸·Î 5¸¦ ´õÇß´Ù°¡ ´Ù½Ã »©´Â °£´ÜÇÑ ¿¬»êÀ» ÇÑ´Ù. ÁÖ ¾²·¹µå´Â ¹«ÇÑ ¹Ýº¹¹®À» µ¹¸é¼ ÇöÀçÀÇ value °ªÀ» °Ë»çÇÑ´Ù.
¸¸¾à °æÀïÀÌ ¾ø´Ù°í »ý°¢Çϸé value °ªÀÇ ¹üÀ§´Â 5¸¦ ´õÇÏÀÚ¸¶ÀÚ ´Ù½Ã »©±â ¶§¹®¿¡ 0 ȤÀº 5ÀÇ °ªÀ» °¡Á®¾ß ÇÑ´Ù.
ÇÏÁö¸¸ ÀÌ °æ¿ì´Â °æÀïÀ» Çϱ⠶§¹®¿¡ ÇÑ ¾²·¹µå°¡ ´õÇϱ⸦ ÇÏ°í ÀÖÀ» ¶§ ´Ù¸¥ ¾²·¹µå°¡ ´õÇϱ⸦ ½ÇÇàÇÒ ¼öµµ ÀÖ¾î 10ÀÌ µÉ ¼öµµ ÀÖ´Ù. ¿©±â±îÁö´Â ½±°Ô Ãß·ÐÇÒ ¼ö°¡ ÀÖ´Ù.
ÁÖ ¾²·¹µå´Â valueÀÇ °ªÀÌ 0¿¡¼ 10À» ¹þ¾î³¯ °æ¿ì¿¡ Ç¥ÁØ Ãâ·ÂÀ¸·Î ±× °ªÀ» Ãâ·ÂÇÏ´Â ÀÏÀ» ÇÑ´Ù. valueÀÇ ¹üÀ§¸¦ °è»êÇϱâ Àü¿¡ °ªÀ» ´Ù¸¥ º¯¼ö·Î º¹»ç¸¦ ÇÑ °ÍÀº ´Ù¸¥ ¾²·¹µå¿¡ ÀÇÇØ ±× °ªÀÌ °è¼Ó º¯Çϱ⠶§¹®¿¡ º¹»ç¸¦ ÇÏÁö ¾ÊÀ¸¸é µÎ °³ÀÇ ºñ±³ ¿¬»êÀÚ¸¦ ¼öÇàÇÏ´Â µ¿¾È value °ªÀÌ º¯ÇÒ ¼ö Àֱ⠶§¹®ÀÌ´Ù.
ÄÄÆÄÀÏÇؼ ½ÇÇàÇØ º¸ÀÚ. ±â´ëÇÑ °á°ú¸¦ º¸¿©Áִ°¡?
> javac NotSynchronizedBlock.java
> java -cp . NotSynchronizedBlock
½ÇÇà °á°ú´Â ¿î¿µ üÁ¦¸¶´Ù Â÷ÀÌ°¡ ³¯ ¼ö ÀÖÁö¸¸, ´ëºÎºÐÀÇ °æ¿ì Á¶±Ý¸¸ ±â´Ù¸®¸é 10º¸´Ù Å©°Å³ª 0º¸´Ù ÀûÀº value °ªµéÀ» ¿½ÉÈ÷ Ãâ·ÂÇÒ °ÍÀÌ´Ù. ±×·¯¸é Ctrl+C¸¦ ÀÔ·ÂÇÏ¿© ÇÁ·Î±×·¥À» °Á¦ Á¾·á½ÃÅ°°í ±× ¿øÀο¡ ´ëÇؼ »ý°¢Çغ¸ÀÚ.
¾î¶»°Ô 10À» ¹þ¾î³¯ ¼ö ÀÖÀ»±î?
value += 5; ¶ó´Â ÇÑ ÁÙÀÇ ¸í·ÉÀº ½ÇÁ¦ ¼öÇàµÉ ¶§¿¡´Â ¿©·¯ °³ÀÇ ÀνºÆ®·°¼ÇÀ¸·Î ³ª´µ¾îÁø´Ù. ÀνºÆ®·°¼ÇÀº ÀÚ¹Ù¿¡¼´Â ÀÚ¹Ù °¡»ó ¸Ó½ÅÀÌ ¼öÇàÇÏ°Ô µÉ ¸í·ÉÀÇ ±âº» ´ÜÀ§¸¦ ³ªÅ¸³»´Âµ¥, À̵é Áß ÀϺο¡ ´ëÇؼ¸¸ ¿øÀÚ¼ºÀ» º¸ÀåÇϵµ·Ï ÀÚ¹Ù °¡»ó ¸Ó½Å ¸í¼¼°¡ Á¤ÇÏ°í ÀÖ´Ù.
¿¬»ê value += 5;°¡ CPU¿¡¼ ½ÇÇàµÉ ¶§ ÇϳªÀÇ ¿¬»êÀÌ ¾Æ´Ï¶ó, ´ÙÀ½°ú °°ÀÌ ¿©·¯ °³ÀÇ ¿¬»êÀ¸·Î ³ª´µ¾îÁø´Ù.
1. º¯¼ö valueÀÇ °ªÀ» ·¹Áö½ºÅÍ·Î ·ÎµåÇÑ´Ù.
2. »ó¼ö 5¸¦ ´õÇÏ´Â ¿¬»êÀ» ·¹Áö½ºÅÍ¿¡ ´ëÇØ ¼öÇàÇÑ´Ù.
3. ¿¬»êÀÇ °á°ú ·¹Áö½ºÅÍ °ªÀ» ¸Þ¸ð¸® º¯¼ö value¿¡ ÀúÀåÇÑ´Ù.
µÎ °³ÀÇ ¾²·¹µå T1, T2¸¦ °¢°¢ ´ÙÀ½°ú °°ÀÌ ½ºÄÉÁÙ¸µµÇ´Â °æ¿ì¸¦ »ý°¢Çغ¸ÀÚ. ·¹Áö½ºÅÍÀÇ °ªÀº ¾²·¹µå º°·Î À¯ÁöµÇ°í, value º¯¼öÀÇ °ªÀº °øÀ¯µÈ´Ù´Â Á¡À» ±â¾ïÇÏÀÚ.
<Ç¥ 3> ½ºÄÉÁÙ¸µ ½Ã³ª¸®¿À
¹øÈ£ |
¾²·¹µå À̸§ |
¿¬»ê |
¿¬»ê Àü value º¯¼öÀÇ °ª |
¿¬»êÀÇ °á°ú°ª |
1 |
T1 |
value + 5 |
0 |
5 |
2 |
T1 |
value = 5 |
5 |
5 |
3 |
T2 |
value + 5 |
5 |
10 |
4 |
T1 |
value - 5 |
5 |
0 |
5 |
T1 |
value = 0 |
0 |
0 |
6 |
T2 |
value = 10 |
10 |
10 |
7 |
T1 |
value + 5 |
10 |
15 |
8 |
T1 |
value = 15 |
15 |
15 |
Ç¥ÀÇ ½ºÄÉÁÙ¸µ ½Ã³ª¸®¿À¿¡ µû¸£¸é T2 ¾²·¹µå°¡ ¿¬»êÀ» ¼öÇàÇÑ °á°ú¸¦ °ª¿¡ ´ëÀÔÇÏ´Â µ¿¾È Áï, 3¹ø°ú 6¹ø ¿¬»ê µ¿¾È¿¡ T1 ¾²·¹µå¿¡¼ ½ÇÇàµÈ ¿¬»êµé Áï, 4¹ø°ú 5¹ø ¿¬»êÀÇ °á°ú°¡ °á°úÀûÀ¸·Î ¹«½Ã°¡ µÇ¾ú´Ù.
ÀÌ·¯ÇÑ ÀÌÀ¯·Î valueÀÇ °ªÀº 10À» ÈξÀ ¹þ¾î³ °ªµµ °¡Áú ¼ö ÀÖ´Â °ÍÀÌ´Ù.
¸¹Àº ¾²·¹µå °æÀï Á¶°Ç°ú µ¥µå¶ô ¹®Á¦¸¦ ÇØ°áÇÏ´Â ¹æ¹ý Áß Çϳª´Â ÀÌ·¯ÇÑ ³í¸®ÀûÀÎ ¿¬»êµéÀÇ ½ÇÇà ¼ø¼¸¦ <Ç¥3>°ú °°ÀÌ ½ÇÁ¦ ¹ß»ý °¡´ÉÇÑ ½Ã³ª¸®¿À¸¦ ÀÛ¼ºÇÑ ÈÄ, ±× ½Ã³ª¸®¿À¿¡ ´ëóÇÏ´Â ¹æ¹ýÀ» ¿¬±¸ÇÏ´Â °ÍÀÌ´Ù.
¿©±â¿¡¼ ¹ß»ýÇÏ´Â ¹®Á¦¸¦ ÇØ°áÇÏ´Â ¹æ¹ýÀº ´ÙÀ½°ú °°´Ù.
°¢ ¿¬»êµéÀÌ ¼öÇàµÇ´Â µ¿¾È ´Ù¸¥ ¾²·¹µå°¡ ´Ù¸¥ ¿¬»êÀ» ¼öÇàÇÏ´Â °ÍÀ» ¸·¾Æ¼ ¹«½ÃµÇ´Â ¿¬»êÀ» ¾ø¾Ö´Â °ÍÀÌ´Ù.
À̶§ ¹°·Ð ÀÚ¹ÙÀÇ ¾²·¹µå µ¿±âÈ¿¡ »ç¿ëµÇ´Â synchronized ºí·ÏÀ» Àû¿ëÇÏ¸é µÈ´Ù.
¿øÀο¡ ´ëÇÑ ºÐ¼®ÀÌ ¸Â¾Ò´Ù¸é ¹«½ÃµÇ´Â °á°ú¸¦ À¯¹ßÇÏÁö ¾Êµµ·Ï value += 5; ȤÀº value -= 5; ¿¬»êÀÌ ¸ðµÎ µ¿±âÈÀÇ ´ÜÀ§°¡ µÇ¸é value°¡ 0º¸´Ù À۰ųª 10º¸´Ù Å« °æ¿ì°¡ ¹ß»ýÇÏÁö ¾ÊÀ» °ÍÀÌ´Ù.
µ¿±âÈ ºí·ÏÀ» Àû¿ëÇÏ´Â °¡Àå Áß¿äÇÑ ¿øÄ¢Àº µ¿±âÈ ºí·ÏÀÇ ¹üÀ§¸¦ °¡´ÉÇÑ ÇÑ Âª°Ô ÇÏ´Â °ÍÀÌ´Ù.
À§¿¡¼ T1, T2 ¾²·¹µåÀÇ run() ¸Þ¼Òµå ¾È¿¡ ÀÖ´Â value += 5; value -= 5; µÎ ¸í·ÉÀ» ¸ðµÎ synchronized ºí·Ï ¾È¿¡ ¹¾îµµ ¹®Á¦¸¦ ÇØ°áÇÒ ¼ö ÀÖÁö¸¸, °¢ ´ÜÀ§ º°·Î ¹´Â °ÍÀÌ µ¿±âÈ ºí·ÏÀÇ ¹üÀ§¸¦ Á¼Çô¼ º¸´Ù ³ªÀº È¿À²À» ±â´ëÇÒ ¼ö ÀÖ´Ù.
<¸®½ºÆ® 2> synchronized ºí·ÏÀ» »ç¿ëÇÑ µ¿±âÈ
while (true) {
synchronized(this) {
value += 5;
}
synchronized(this) {
value -= 5;
}
}
¼öÁ¤ÇÑ ¹öÀüÀ» ÄÄÆÄÀÏÇؼ ½ÇÇàÇغ¸¸é ¾Æ¹«·± ¸Þ½ÃÁöµµ Ãâ·ÂÇÏÁö ¾ÊÀ½À» º¼ ¼ö ÀÖÀ» °ÍÀÌ´Ù.
µ¥µå¶ô
µ¥µå¶ô(deadlock)Àº µÑ ÀÌ»óÀÇ ¾²·¹µå°¡ ½ÇÇàÀ» ¸ØÃß°í °áÄÚ ¹ß»ýÇÏÁö ¾ÊÀ» Á¶°ÇÀ» ±â´Ù¸®±â ¶§¹®¿¡ ´õ ÀÌ»ó ÁøÇàÇÒ ¼ö ¾ø´Â ±³Âø »óÅ¿¡ ºüÁö´Â °ÍÀ» ÀǹÌÇÑ´Ù. µ¥µå¶ôÀº ´Ù¾çÇÑ ÀÌÀ¯·Î ¹ß»ýÇÒ ¼ö ÀÖ´Ù.
¿¹¸¦ µé¾î T1 ¾²·¹µå°¡ a ¸ð´ÏÅÍÀÇ Àá±ÝÀ» ¾òÀº ÈÄ b ¸ð´ÏÅÍÀÇ Àá±ÝÀ» ¾òÀ¸·Á ÇÏ°í, T2 ¾²·¹µå´Â b ¸ð´ÏÅÍÀÇ Àá±ÝÀ» ¾òÀº ÈÄ a ¸ð´ÏÅÍÀÇ Àá±ÝÀ» ¾òÀ¸·Á ÇÏ´Â »óȲÀ» »ý°¢Çغ¸ÀÚ.
T1 ¾²·¹µå´Â T2 ¾²·¹µå°¡ b ¸ð´ÏÅÍÀÇ Àá±ÝÀ» Ç®±â¸¦ ±â´Ù¸®°í, T2 ¾²·¹µå´Â T1 ¾²·¹µå°¡ a ¸ð´ÏÅÍÀÇ Àá±ÝÀ» Ç®±â¸¦ ±â´Ù¸°´Ù.
µÎ ¾²·¹µå´Â ¹«ÇÑÈ÷ ±â´Ù¸± ¼ö ¹Û¿¡ ¾ø´Ù. ÀÌ »óÅ°¡ ¹Ù·Î µ¥µå¶ôÀÌ´Ù. µ¥µå¶ôÀº µ¿±âÈ ºí·ÏÀÌ À߸ø »ç¿ëµÇ´Â °æ¿ì¿¡ Á¾Á¾ ¹ß»ýÇÑ´Ù.
´ÙÀ½ ¿¹Á¦´Â µ¥µå¶ô »óȲÀ» ÀÓÀÇ·Î ¸¸µç´Ù.
<¸®½ºÆ® 3> Deadlock.java ¼Ò½º ÄÚµå
public class Deadlock {
Object a = new Object(); // a ¸ð´ÏÅÍ °´Ã¼
Object b = new Object(); // b ¸ð´ÏÅÍ °´Ã¼
void doit() {
new Thread("T1") {
public void run() {
synchronized(a) {
System.out.println("T1 acquired a");
// µ¥µå¶ô »óȲÀ» ¸¸µé±â À§ÇØ 1ÃÊ Á¤µµ ±â´Ù¸²
try { Thread.sleep(1000); } catch (InterruptedException e) {}
synchronized(b) {
System.out.println("T1 acquired b");
}
}
}
}.start(); // T1 ¾²·¹µå ½ÃÀÛ
new Thread("T2") {
public void run() {
synchronized(b) {
System.out.println("T2 acquired b");
// µ¥µå¶ô »óȲÀ» ¸¸µé±â À§ÇØ 1ÃÊ Á¤µµ ±â´Ù¸²
try { Thread.sleep(1000); } catch (InterruptedException e) {}
synchronized(a) {
System.out.println("T2 acquired a");
}
}
}
}.start(); // T2 ¾²·¹µå ½ÃÀÛ
}
public static void main(String[] args) {
new Deadlock().doit();
}
}
¿¹Á¦¿¡¼ T1 ¾²·¹µå´Â ¸ÕÀú ¸ð´ÏÅÍ °´Ã¼ a¿¡ ´ëÇÑ Àá±ÝÀ» ¾òÀº ´ÙÀ½ 1ÃÊ Á¤µµ ½® ´ÙÀ½ ¸ð´ÏÅÍ °´Ã¼ b¿¡ ´ëÇÑ Àá±ÝÀ» ¾òÀ¸·Á°í ½ÃµµÇÏ°í, T2 ¾²·¹µå´Â ¸ð´ÏÅÍ °´Ã¼ b¿¡ ´ëÇÑ Àá±ÝÀ» ¾òÀº ´ÙÀ½ ¿ª½Ã 1ÃÊ Á¤µµ ½® ÈÄ ¸ð´ÏÅÍ °´Ã¼ a¿¡ ´ëÇÑ Àá±ÝÀ» ¾òÀ¸·Á°í ½ÃµµÇÑ´Ù.
1ÃÊ Á¤µµ ½¬´Â ÀÌÀ¯´Â °¢ ¾²·¹µå°¡ ÇϳªÀÇ Àá±Ý¸¸À» ¾òµµ·Ï À¯µµÇϱâ À§ÇؼÀÌ´Ù. ¹°·Ð ¿î¿µ üÁ¦¿Í ½ÇÇà ȯ°æ¿¡ µû¶ó ´Þ¶óÁú ¼ö Àֱ⠶§¹®¿¡ 1ÃÊ ½®´Ù°í ¹Ýµå½Ã ÀÌ µ¥µå¶ô »óȲÀ» º¸ÀåÇØÁÖ´Â °ÍÀº ¾Æ´Ï´Ù. ¿©±â¿¡¼´Â ÆíÀÇ»ó µ¥µå¶ôÀÇ È®·üÀ» ³ô¿©ÁÖ±â À§ÇØ µÎ ¾²·¹µå°¡ 1Ãʾ¿ ½¬¾ú´Ù.
ÄÄÆÄÀÏÇÏ¿© ½ÇÇàÇغ¸¸é ´ëºÎºÐÀÇ °æ¿ì
T1 acquired a
T2 acquired b
¸Þ½ÃÁö¸¸ Ãâ·ÂµÇ°í ±× ´ÙÀ½À¸·Î ÁøÇàÀÌ µÇÁö ¾ÊÀ» °ÍÀÌ´Ù.
ÀÚ¹Ù °¡»ó ¸Ó½ÅÀº ÇöÀç ÁøÇà ÁßÀÎ ¾²·¹µåµéÀÇ ÄÝ ½ºÅÃÀ» ´ýÇÁÇؼ º¸¿©ÁÖ´Â Æí¸®ÇÑ ±â´ÉÀ» °¡Áö°í Àִµ¥, À¯´Ð½º³ª ¸®´ª½º ȯ°æ¿¡¼´Â QUIT ½Ã±×³ÎÀ» ÇØ´ç ÀÚ¹Ù ÇÁ·Î¼¼½º¿¡ º¸³»¸é (ȤÀº, ÀÚ¹Ù ÇÁ·Î±×·¥À» ½ÇÇà½ÃŲ Äֿܼ¡¼ Ctrl+\ Å°¸¦ ´©¸£¸é) ÇØ´ç ÄַܼΠÄÝ ½ºÅÃÀ» ´ýÇÁÇؼ º¸¿©ÁÖ¸ç, À©µµ¿ì ȯ°æÀÏ °æ¿ì ÀÚ¹Ù¸¦ ½ÇÇà½ÃŲ ¸í·É ÇÁ·ÒÇÁÆ® â¿¡¼ Ctrl+BREAK Å°¸¦ ´©¸£¸é ÇØ´ç ¸í·É ÇÁ·ÒÇÁÆ®·Î ÄÝ ½ºÅÃÀ» º¸¿©ÁØ´Ù.
´ÙÀ½Àº ÇÊÀÚÀÇ À©µµ¿ì ȯ°æ¿¡¼ ÀÌ µ¥µå¶ô »óȲ¿¡ ´ëÇÑ ¾²·¹µå ´ýÇÁ ¿¹ÀÌ´Ù.
<¸®½ºÆ® 4> µ¥µå¶ô »óȲ¿¡ ´ëÇÑ ¾²·¹µå ÄÝ ½ºÅà ´ýÇÁ Áß ÀϺÎ
Full thread dump Java HotSpot(TM) Client VM (1.4.2_04-b05 mixed mode):
...
"T2" prio=5 tid=0x008ef3f0 nid=0x81c waiting for monitor entry [2d2f000..2d2fd8c]
at Deadlock$2.run(Deadlock.java:50)
- waiting to lock <0x10030e48> (a java.lang.Object)
- locked <0x10030e50> (a java.lang.Object)
"T1" prio=5 tid=0x008ef6a0 nid=0x220 waiting for monitor entry [2cef000..2cefd8c]
at Deadlock$1.run(Deadlock.java:36)
- waiting to lock <0x10030e50> (a java.lang.Object)
- locked <0x10030e48> (a java.lang.Object)
...
Found one Java-level deadlock:
=============================
"T2":
waiting to lock monitor 0x008d86b4 (object 0x10030e48, a java.lang.Object),
which is held by "T1"
"T1":
waiting to lock monitor 0x008d8694 (object 0x10030e50, a java.lang.Object),
which is held by "T2"
...
Found 1 deadlock.
À§ÀÇ ¸®½ºÆ®¿¡¼ º¼ ¼ö ÀÖµíÀÌ, ÀÚ¹Ù 2 SDK 1.4.2 HotSpot °¡»ó ¸Ó½ÅÀº Ä£ÀýÇÏ°Ô µ¥µå¶ôÀ» °ËÃâÇÏ¿© º°µµ·Î Ç¥½Ã±îÁö ÇØÁØ´Ù. ÇÏÁö¸¸, °¡»ó ¸Ó½ÅÀÌ ´Ù¸¦ °æ¿ì, Ç×»ó ±â´ëÇÒ ¼ö ÀÖ´Â °ÍÀº ¾Æ´Ï¹Ç·Î ¾²·¹µåº° Á¤º¸¸¦ ÀÐ¾î¼ µ¥µå¶ô »óȲÀ» ã¾Æº¼ ÇÊ¿ä°¡ ÀÖ´Ù.
¸Ç ¾Õ ºÎºÐÀÇ µû¿ÈÇ¥·Î ³ªÅ¸³ ºÎºÐÀÌ ¾²·¹µå À̸§ÀÌ´Ù. ¾²·¹µå À̸§À» ÁöÁ¤ÇØÁÖÁö ¾ÊÀ» °æ¿ì, ³»ºÎÀûÀ¸·Î À̸§À» ÇÒ´çÇÏ°Ô µÇ´Âµ¥, ¿©±â¿¡¼´Â ¾²·¹µå °´Ã¼¸¦ ¸¸µé ¶§ T1, T2¶ó´Â À̸§À» ¸í½ÃÇÏ¿´À¸¹Ç·Î ã¾Æº¸±â°¡ ÆíÇÏ´Ù. ¾²·¹µå ÇÁ·Î±×·¡¹ÖÇÒ ¶§ ¾²·¹µå À̸§À» ¾î¶² ¸í¸í °ü·Ê¿¡ µû¶ó ÁöÁ¤Çϵµ·Ï ±ÇÀåÇÏ´Â °ÍÀº ÁÁÀº ÇÁ·Î±×·¡¹Ö ½À°üÀÌ´Ù.
T2 ¾²·¹µåÀÇ ÄÝ ½ºÅà Á¤º¸¿¡¼ °¡Àå ¹Ø ºÎºÐ¿¡ 0x10030e50À̶ó´Â ObjectÀÇ ¸ð´ÏÅÍ °´Ã¼¿¡ ´ëÇØ Àá±ÝÀ» ¾ò¾ú°í, ±× À ÁÙ¿¡ 0x10030e48À̶ó´Â ObjectÀÇ ¸ð´ÏÅÍ °´Ã¼¿¡ ´ëÇØ Àá±ÝÀ» ¾ò±â À§ÇØ ±â´Ù¸®°í ÀÖ´Ù´Â Á¤º¸°¡ ÀÖ´Ù. T1 ¾²·¹µåÀÇ ÄÝ ½ºÅà Á¤º¸¿¡¼´Â ±× ¹Ý´ëÀÇ Á¤º¸¸¦ ¾òÀ» ¼ö ÀÖ´Ù. ÀÌ°ÍÀ» À¯ÃßÇÏ¿© µ¥µå¶ô »óȲÀ» ÆÇ´ÜÇÏ°í, ±× ¿øÀÎÀ» ã¾Æ ÇØ°áÇÏ´Â ³ë·ÂÀÌ ¾²·¹µå ¹®Á¦ ÇØ°áÀ» À§ÇØ ¿ä±¸µÈ´Ù.
µ¿±âÈÀÇ ºñ¿ë
µ¿±âȸ¦ »ç¿ëÇÏ´Â °ÍÀº »ç¿ëÇÏÁö ¾Ê´Â °Í¿¡ ºñÇØ »ó´çÇÑ ºñ¿ëÀÌ µç´Ù´Â °ÍÀº ¸ðµÎ ¾Ë°í ÀÖÀ» °ÍÀÌ´Ù.
Ưº°È÷ º°µµÀÇ ¿¹¸¦ µéÁö ¾Ê´õ¶óµµ, java.util ÆÐÅ°ÁöÀÇ ¿©·¯ Ä÷º¼Ç Ŭ·¡½ºµé¿¡ ´ëÇØ µ¿±âȸ¦ ÇÑ ¹öÀü°ú ÇÏÁö ¾ÊÀº ¹öÀüÀÌ »ó´çÇÑ ¼öÇà ¼º´É Â÷ÀÌ°¡ ÀÖÀ½Àº ÀÍÈ÷ µé¾î ¾Ë°í ÀÖÀ» °ÍÀÌ´Ù.
´ëºÎºÐÀÇ °æ¿ì µ¿±âȸ¦ ÃÖ¼ÒÈÇÏ´Â °ÍÀÌ °¡Àå ÁÁÀº ¼º´ÉÀ» º¸¿©ÁÖ¸ç, À߸øµÈ µ¿±âÈ »ç¿ëÀº µ¥µå¶ô°ú °°Àº Ä¡¸íÀûÀÎ °áÇÔÀ» À¯¹ßÇÏ°Ô µÈ´Ù. ¶Ç, ¾Õ¿¡¼ ÁöÀûÇÑ ´ë·Î synchronized¸¦ »ç¿ëÇÑ µ¿±âÈ ºí·ÏÀÇ °æ¿ì °¡´ÉÇÏ¸é ±× ¿µ¿ªÀÌ Á¼À» ¼ö·Ï, ¶Ç ½ÇÁ¦ ¼öÇà ½Ã°£ÀÌ ÂªÀ» ¼ö·Ï ÁÁ´Ù.
¾Æ·¡ÀÇ µÎ ¸Þ¼Òµå doit()°ú doit2()´Â µ¿±âÈÀÇ °üÁ¡¿¡¼ º¼ ¶§ µ¿ÀÏÇÑ ÀÏÀ» ÇÑ´Ù. ±×·¸´Ù¸é, doit()ÀÌ ÁÁÀº ÇüÅÂÀÏ°¡, doit2()°¡ ÁÁÀº ÇüÅÂÀÏ°¡?
void doit() {
synchronized(this) {
doSomething();
}
}
synchronized void doit2() {
doSomething();
}
ÀϹÝÀûÀ¸·Î ¸Þ¼Òµå Àüü¿¡ ´ëÇÑ µ¿±âȸ¦ ÇÒ °æ¿ì¿¡´Â doit2()ÀÇ °æ¿ì¿Í °°ÀÌ ¸Þ¼Òµå¿¡¼ Á÷Á¢ synchronized Á¦ÇÑÀÚ¸¦ »ç¿ëÇÏ´Â °ÍÀÌ º¸´Ù ³ªÀº ¼º´ÉÀ» º¸ÀåÇÑ´Ù´Â ÃøÁ¤ °á°ú°¡ ÀÖ´Ù.
ÀÌ°ÍÀº ÀÚ¹Ù °¡»ó ¸Ó½ÅÀÌ ¼öÇàÇÏ°Ô µÉ ÀÚ¹Ù ¹ÙÀÌÆ® ÄÚµåÀÇ Â÷ÀÌ¿¡¼µµ È®ÀÎÇÒ ¼ö ÀÖ´Ù. À§ µÎ ¸Þ¼Òµå¸¦ ÀÚ¹Ù 2 SDK¿¡ Æ÷ÇÔµÈ javap ÇÁ·Î±×·¥À» »ç¿ëÇÏ¿© ¿ªÄÄÆÄÀÏÇغ¸¸é ´ÙÀ½°ú °°ÀÌ ³ªÅ¸³´Ù.
<¸®½ºÆ® 5> µ¿±âÈ ºí·ÏÀ» Æ÷ÇÔÇÑ ¸Þ¼ÒµåÀÇ ¿ªÄÄÆÄÀÏ °á°ú
void doit();
Code:
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: aload_0
5: invokevirtual #3; //Method doSomething:()V
8: aload_1
9: monitorexit
10: goto 18
13: astore_2
14: aload_1
15: monitorexit
16: aload_2
17: athrow
18: return
Exception table:
from to target type
4 10 13 any
13 16 13 any
synchronized void doit2();
Code:
0: aload_0
1: invokevirtual #3; //Method doSomething:()V
4: return
ÀÌ °á°ú¿¡¼ º¼ ¼ö ÀÖµíÀÌ, °¡»ó ¸Ó½ÅÀÌ ¼öÇàÇØ¾ß µÉ ÀνºÆ®·°¼ÇÀÇ °¹¼ö°¡ Å©°Ô Â÷ÀÌ°¡ ³ª°í, °¡»ó ¸Ó½ÅÀÌ ÃÖÀûȸ¦ ¼öÇàÇÒ ¿©Áö ¶ÇÇÑ ÁÙ¾îµç´Ù´Â °ÍÀ» º¼ ¼ö ÀÖ´Ù.
ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨
ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨
´ÙÁß ¾²·¹µå ȯ°æ¿¡¼ ÀÚ¹Ù´Â ÃÖÀûȸ¦ À§ÇØ ¿©·¯ °¡Áö ±â¹ýÀ» Çã¿ëÇÑ´Ù. ÀÌ·¯ÇÑ ÃÖÀûÈ ±â¹ýÀº ¿©·¯ °³ÀÇ CPU·Î ±¸¼ºµÈ ´ëĪÇü ´ÙÁß ÇÁ·Î¼¼¼(SMP) ¸Ó½Å¿¡¼ ½ÇÇàµÉ °æ¿ì Á»´õ º¹ÀâÇÑ ¹®Á¦¸¦ ³ºÀ» ¼ö ÀÖ´Ù. ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨Àº Ãß»óÈµÈ °³³äÀ¸·Î °¢ ÀÚ¹Ù °¡»ó ¸Ó½ÅÀÌ ÁöÄÑ¾ß ÇÏ´Â ÃÖ¼ÒÇÑÀÇ ±ÔÄ¢À» Á¤ÀÇÇÑ´Ù. µû¶ó¼, ½ÇÁ¦ ÀÚ¹Ù °¡»ó ¸Ó½ÅÀº ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨º¸´Ù Á»´õ ¾ö°ÝÇÑ ±ÔÄ¢À¸·Î ±¸ÇöµÉ ¼ö ÀÖ´Ù.
´ÙÀ½ ±×¸²Àº µÎ °³ÀÇ CPU°¡ ÀÖ´Â SMP ¸Ó½ÅÀ» º¸¿©ÁØ´Ù.
<±×¸² 1> µÎ °³ÀÇ CPU·Î ±¸¼ºµÈ SMP ¸Ó½Å
ÀÚ¹ÙÀÇ °¢ º¯¼ö´Â ¸Þ¸ð¸®¿¡ ÀúÀåµÇ¾î ÀÖÁö¸¸, ¿¬»ê ½Ã¿¡´Â ·¹Áö½ºÅÍ¿¡ ÀûÀçµÇ¾î CPU¿¡¼ ¿¬»êÀ» ¼öÇàÇÑ ÈÄ ´Ù½Ã ¸Þ¸ð¸®·Î ÀúÀåµÇ¾î¾ß ÇÑ´Ù.
´ÙÁß ÇÁ·Î¼¼¼ ȯ°æ¿¡¼ °í·ÁÇØ¾ß ÇÒ ¸î °¡Áö ¾²·¹µå À̽´´Â ´ÙÀ½ ¼¼ °¡Áö·Î ºÐ·ùµÈ´Ù.
(1) ¿øÀÚ¼º
¸Þ¸ð¸®¿¡ ÀÖ´Â ÇÊµå º¯¼ö¸¦ Àаųª ¾µ ¶§, ÇÑ ¾²·¹µå°¡ ÇØ´ç ÇÊµå º¯¼ö¿¡ ´ëÇØ ¾²´Â ¸í·ÉÀ» ¼öÇàÇÏ´Â µ¿¾È ´Ù¸¥ ¾²·¹µå°¡ °°Àº º¯¼ö¿¡ ´ëÇØ Àаųª ¾µ °æ¿ì, ±× °á°ú°¡ ¾î´À ÇÑ ¾²·¹µåÀÇ µ¿ÀÛÀ¸·Î º¸ÀåµÇ¾î¾ß ÇÑ´Ù. Áï, Àаųª ¾´ °á°ú°¡ ¾²´Â µµÁßÀÇ °ÍÀÌ µÇ¾î ÀϺΠºñÆ®¸¸ º¯°æµÈ °ªÀÌ µÇ°Å³ª µÎ ¾²±â ¸í·ÉÀÇ °á°ú°¡ ¼¯¿©¼ ¿øÇÏÁö ¾Ê´Â °ªÀÌ µÇÁö ¾Ê´Â´Ù´Â °ÍÀÌ º¸ÀåµÇ¾î¾ß ÇÑ´Ù. ¾î¶² ¸í·ÉÀº ÀÌ°ÍÀÌ º¸ÀåµÇ°í, ¾î¶² ¸í·ÉÀº ÀϺθ¸ º¯°æµÇ´Â °ªÀÌ ³ª¿Ã °¡´É¼ºÀÌ Á¸ÀçÇÑ´Ù. ÀÌ°ÍÀ» ¿øÀÚ¼º(atomicity)¶ó°í ºÎ¸¥´Ù.
(2) °¡½Ã¼º
µÎ °³ÀÇ ¾²·¹µå°¡ °¢°¢ ´Ù¸¥ CPU¿¡¼ ½ÇÇàµÇ¸é¼ °°Àº º¯¼ö¿¡ ´ëÇØ ¿¬»êÀ» ¼öÇàÇÒ °æ¿ì, ¿¬»ê °á°ú¸¦ ¸Þ¸ð¸®·Î ÀúÀåÇÏ´Â ½ÃÁ¡ÀÌ ÃÖÀûȵǾî ÇÑ ¾²·¹µå°¡ ¿¬»êÀ» ¼öÇàÇÑ °á°ú¸¦ ´Ù¸¥ ¾²·¹µå°¡ ¹Ù·Î º¼ ¼ö ¾ø´Â °æ¿ì°¡ ÀÖ´Ù. ÀÌ°ÍÀ» ¾²·¹µåÀÇ °¡½Ã¼º(visibility)À̶ó°í ºÎ¸¥´Ù.
(3) ½ÇÇà ¼ø¼
ÄÚµå »óÀÇ ¿¬»ê ¼ø¼°¡ ½ÇÁ¦·Î CPU¿¡¼ ¼öÇàµÇ´Â ¼ø¼¿Í´Â ´Ù¸¦ ¼ö ÀÖ´Ù. ÀÌ°ÍÀº ÄÄÆÄÀÏ·¯ÀÇ ÃÖÀûÈ¿¡ ÀÇÇØ ¹ß»ýÇÏ´Â °ÍÀ¸·Î ÇϳªÀÇ ¾²·¹µå¿¡¼´Â °ü°è°¡ ¾øÁö¸¸, ´Ù¸¥ ¾²·¹µå°¡ °°Àº º¯¼ö¸¦ ÂüÁ¶ÇÒ °æ¿ì ¿¬»êÀÇ ½ÇÇà ¼ø¼ÀÇ Â÷ÀÌ°¡ ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù. ÀÌ°ÍÀ» ¾²·¹µåÀÇ ½ÇÇà ¼ø¼(ordering)¶ó°í ºÎ¸¥´Ù.
ÀÚ¹Ù·Î ¿©·¯ °³ÀÇ ¾²·¹µå°¡ °ü·ÃµÈ ÇÁ·Î±×·¥À» ÀÛ¼ºÇÒ ¶§ ÀÌ ¼¼ °¡Áö ¿ä¼Ò¸¦ ¸ðµÎ °í·ÁÇÏ¿©¾ß ÇÑ´Ù.
¸ÕÀú ¿øÀÚ¼ºÀÇ °æ¿ì, ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨Àº 64ºñÆ®ÀÎ long°ú doubleÀ» Á¦¿ÜÇÑ ±âº» ÀÚ·áÇü¿¡ ´ëÇØ Àбâ¿Í ¾²±âÀÇ ¿øÀÚ¼ºÀ» º¸ÀåÇÑ´Ù. ¶Ç, long°ú double Çʵ尡 volatile·Î ¼±¾ðµÈ °æ¿ì¿¡µµ ÀÌ Çʵ忡 ´ëÇÑ Àбâ¿Í ¾²±âÀÇ ¿øÀÚ¼ºÀ» º¸ÀåÇÑ´Ù.
Àбâ¿Í ¾²±âÀÇ ¿øÀÚ¼ºÀÌ º¸ÀåµÇ´Â int¿Í °°Àº ÀÚ·áÇü Çʵ带 ÇÑ ¾²·¹µå°¡ °ªÀ» º¯°æÇÏ¿´À» ¶§ ´Ù¸¥ ¾²·¹µå°¡ ¹Ù·Î ±× °á°ú¸¦ º¼ ¼ö ÀÖ´Â °ÍÀº ¾Æ´Ï´Ù. ÀÌ°ÍÀÌ ¹Ù·Î °¡½Ã¼º ¹®Á¦·Î, ´Ù¸¥ ¾²·¹µå°¡ ±× °á°ú¸¦ º¼ ¼ö ÀÖ´Ù°í º¸ÀåµÇ´Â °æ¿ì´Â volatile ÇʵåÀÎ °æ¿ì¿Í synchronized ºí·ÏÀ¸·Î µ¿±âÈÇÏ´Â °æ¿ìÀÌ´Ù. ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨Àº volatile ÇʵåÀÇ °æ¿ì ÇÑ ¾²·¹µå¿¡¼ ¾²±â¸¦ ÇÑ °æ¿ì ¹Ù·Î ´Ù¸¥ ¾²·¹µå°¡ º¼ ¼ö ÀÖÀ½À» º¸ÀåÇÑ´Ù. ¶Ç, ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨Àº synchronized ºí·Ï ¼öÇà µµÁß Àá±Ý °´Ã¼¸¦ Ç® ¶§, µ¿±âÈ ±¸°£¿¡¼ º¯°æÇÑ °á°ú°¡ ¸ðµÎ ¸Þ¸ð¸®¿¡ ¹Ý¿µµÊÀ» º¸ÀåÇÑ´Ù.
volatileµµ synchronized ºí·Ïµµ »ç¿ëÇÏÁö ¾ÊÀº °æ¿ì¿¡´Â ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨Àº º¯È°¡ ¸Þ¸ð¸®¿¡ ¹Ý¿µµÇ´Â Á¤È®ÇÑ ½ÃÁ¡¿¡ ´ëÇØ ¾Æ¹«·± º¸ÀåÀ» ÇÏÁö ¾Ê´Â´Ù.
µû¶ó¼, ´ÙÀ½ µÎ ¸Þ¼Òµå´Â ¼·Î ´Ù¸£°Ô µ¿ÀÛÇÑ´Ù. ¿øÀÚ¼ºÀÇ °üÁ¡¿¡¼ º¸¸é synchronized´Â ºÒÇÊ¿äÇÑ ¿À¹öÇìµå°¡ µÇÁö¸¸, ¸¸¾à ÀÌ °ªÀÇ º¯È¸¦ ´Ù¸¥ ¾²·¹µå°¡ ¹Ù»Ú°Ô ±â´Ù¸®°í ÀÖ´Ù¸é ±× °ªÀÌ Àü´ÞµÇ´Â ½ÃÁ¡ÀÌ º¸ÀåµÇ´Â synchronized ¹öÀüÀ» »ç¿ëÇØ¾ß ÇÒ °ÍÀÌ´Ù.
synchronized void setValue(int a) {
this.a = a;
}
void setValue(int a) {
this.a = a;
}
¾²·¹µåÀÇ ½ÇÇà ¼ø¼ÀÇ °æ¿ì¿¡µµ ¸¶Âù°¡Áö ¹®Á¦°¡ ¹ß»ýÇÑ´Ù. ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨Àº volatile Çʵ忡 ´ëÇÑ ¿¬»êÀÇ °æ¿ì ±× ½ÇÇà ¼ø¼¸¦ º¸ÀåÇÑ´Ù. ¶Ç, synchronized ºí·Ï¿¡¼ Àá±ÝÀ» ¾ò°í, Ç® ¶§ÀÇ °æ¿ì´Â µ¿±âȸ¦ ÅëÇØ ¼ø¼ÀÇ ¹®Á¦°¡ ¹ß»ýÇÏÁö ¾ÊÀ¸¸ç, ´ÜÀÏ ¾²·¹µå¿¡¼ ½ÇÇàµÉ °æ¿ì¿¡µµ ¼ø¼ÀÇ ¹®Á¦´Â ¹ß»ýÇÏÁö ¾Ê´Â´Ù. ÇÏÁö¸¸, µ¿±âȸ¦ »ç¿ëÇÏÁö ¾Ê´Â ´Ù¸¥ ¾²·¹µå°¡ ¹Ù»Ú°Ô ½ÇÇà ¼ø¼¿¡ °ü·ÃµÈ ÇʵåµéÀ» °Ë»çÇÏ°í ÀÖ°í, ¶Ç º¯È½ÃÅ°·Á ÇÑ´Ù¸é ¾î¶² °á°ú°¡ ³ª¿ÃÁö ¸Þ¸ð¸® ¸ðµ¨Àº º¸ÀåÇÏÁö ¾Ê´Â´Ù.
Á¤¸®ÇÏÀÚ¸é, volatile°ú µ¿±âÈ ºí·ÏÀº ¿©·¯ ¾²·¹µå°¡ °øÀ¯ÇÏ´Â º¯¼ö¿¡ °ü·ÃµÈ ¿øÀÚ¼º, °¡½Ã¼º, ±×¸®°í ½ÇÇà ¼ø¼¿¡ ´ëÇØ ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨ÀÌ º¸ÀåÇÑ´Ù. ±×·¸Áö ¾ÊÀº °æ¿ì¿¡´Â ·¹Áö½ºÅÍÀÇ °ªÀÌ ¸Þ¸ð¸®·Î ¹Ý¿µµÇ±â Àü¿¡ ´Ù¸¥ ¾²·¹µå°¡ ´Ù½Ã ¼öÁ¤Çϰųª ½ÇÇà ¼ø¼°¡ ´Þ¶óÁú ¼ö ÀÖ´Ù. °¢ ÇÁ·Î±×·¥ÀÇ ÇÊ¿ä¿¡ µû¶ó µ¿±âÈÀÇ ¿À¹öÇìµå¸¦ °í·ÁÇÏ¿© ÀûÀýÇÑ ¹æ½ÄÀ» ¼±ÅÃÇØ¾ß ÇÑ´Ù.
ƯÈ÷ ºí·ÎÅ· ¿¬»êÀ» »ç¿ëÇÏÁö ¾Ê°í ¾î¶² Á¶°ÇÀ» ¸¸Á·ÇÒ ¶§±îÁö ¹«ÇÑ ¹Ýº¹¹®À» µ¹¸é¼ ¹Ù»Ú°Ô °Ë»çÇÏ´Â busy wait ¹æ½ÄÀÇ °æ¿ì¿¡´Â volatile ÇʵåÀÇ »ç¿ëÀÌ ÇÊ¿äÇÏ´Ù.
ÁÖÀÇÇÒ °ÍÀº ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨¿¡¼ Á¤ÇÏ°í ÀÖ´Â volatile ÇʵåÀÇ µ¿ÀÛ ¹æ½ÄÀ» Á¦´ë·Î ±¸ÇöÇÏ°í ÀÖ´Â ÀÚ¹Ù °¡»ó ¸Ó½ÅÀÌ ¸¹Áö ¾Ê´Ù´Â Á¡ÀÌ´Ù. ÀÚ¹Ù 2 SDK¿¡ Æ÷ÇÔµÈ °¡»ó ¸Ó½ÅÀÇ °æ¿ì 1.4 ¹öÀüºÎÅÍ ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨À» Á¦´ë·Î ó¸®ÇÏ°í ÀÖ´Ù.
ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨ÀÇ ³»¿ëÀº ÇöÀç ÀÚ¹Ù ½ºÆå ¿äû(JSR) 133¹ø¿¡¼ °è¼Ó ³íÀÇ°¡ ÁøÇàµÇ°í ÀÖ´Ù. ºÒºÐ¸íÇÑ ÀÚ¹Ù ¾ð¾î ¸í¼¼ÀÇ ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨ °ü·Ã ³»¿ëÀ» Á»´õ ¾ö¹ÐÇÏ°Ô Á¤ÀÇÇϱâ À§ÇÑ ³íÀÇÀε¥, ¸¹Àº ºÎºÐÀº ÀÚ¹Ù 2 SDK 1.4 ¹öÀü¿¡ ÀÌ¹Ì ±¸ÇöµÈ °ÍÀ» Á»´õ ³í¸®ÀûÀ¸·Î ¾ö¹ÐÇÏ°Ô ÇÏ´Â ³»¿ëÀÌ µÉ °ÍÀÌ´Ù. JSR 133¹ø¿¡¼ ÀÛ¼º ÁßÀÎ ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨ °ü·Ã ¹®¼´Â Âü°í ÀÚ·á¿¡ ÀÖ´Â URLÀ» Âü°íÇϱ⠹ٶõ´Ù.
¡°ÀÌÁß °Ë»ç ¹æ½ÄÀÇ Àá±ÝÀº µ¿ÀÛÇÏÁö ¾Ê´Â´Ù¡± ¼±¾ð
ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨¿¡¼´Â volatile º¯¼ö¿¡ Á¢±ÙÇÒ ¶§³ª synchronized ºí·Ï¿¡¼ Àá±Ý °´Ã¼¸¦ ȹµæÇϰųª Ç® ¶§¸¦ Á¦¿ÜÇÏ°í´Â ±Ø´ÜÀûÀ̶ó°í ÇÒ¸¸Å °ü´ëÇÑ ±ÔÄ¢À» Àû¿ëÇÑ´Ù. ÀÌ¿Í °ü·ÃÇÏ¿© À¯¸íÇÑ ³íÀïÀº ÀÌÁß °Ë»ç ¹æ½ÄÀÇ Àá±ÝÀÌ ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨ ¾Æ·¡¿¡¼´Â µ¿ÀÛÇÏÁö ¾Ê´Â´Ù´Â °ÍÀÌ´Ù.
ÀÌÁß °Ë»ç Àá±ÝÀ̶õ ¾î¶² °´Ã¼¸¦ ÇÊ¿äÇÑ °æ¿ì¿¡¸¸ »ý¼ºÇÏ´Â lazy initialization ¹æ½ÄÀ¸·Î ¸¸µé ¶§, ¿©·¯ °³ÀÇ ¾²·¹µå°¡ Á¢±ÙÇÒ °æ¿ì¸¦ °í·ÁÇÏ¿© µ¿±âȸ¦ ÃÖ¼ÒÈÇÏ´Â °æ¿ìÀÌ´Ù.
¿¹½ÃÇÏ´Â getHelper() ¸Þ¼Òµå´Â ´ÙÁß ¾²·¹µå ȯ°æ¿¡¼ ´ÙÀ½°ú °°ÀÌ ±¸ÇöÇÏ¸é °£´ÜÇÏ´Ù.
public synchronized Helper getHelper() {
if (helper == null) {
helper = new Helper();
}
return helper;
}
ÇÏÁö¸¸ ÇØ´ç °´Ã¼¸¦ »ý¼ºÇÒ ¶§»Ó¸¸ ¾Æ´Ï¶ó ¸Å¹ø Á¢±ÙÇÒ ¶§¸¶´Ù µ¿±âÈ ºí·ÏÀ» °ÅÃÄ¾ß ÇϹǷÎ, ¼öÇà ¼º´ÉÀ» °³¼±Çϱâ À§ÇØ, ¸ÕÀú °´Ã¼°¡ ÀÖ´ÂÁö ¿©ºÎ¸¦ µ¿±âÈ ºí·Ï ¹Û¿¡¼ °Ë»çÇÑ ´ÙÀ½ ¾øÀ» °æ¿ì¿¡¸¸ µ¿±âÈ ºí·ÏÀ» »ç¿ëÇÏ¿© °´Ã¼¸¦ »ý¼ºÇϵµ·Ï ÇÑ °ÍÀÌ ÀÌÁß °Ë»ç ¹æ½ÄÀÇ Àá±ÝÀÌ´Ù. ÀÌÁß °Ë»ç¶ó´Â À̸§Àº synchronized ºí·Ï ¾È¿¡¼ Çѹø ´õ °Ë»ç¸¦ ÇÑ´Ù´Â Àǹ̿¡¼ ºÙ¿©Áø À̸§ÀÌ´Ù.
´ÙÀ½ ºÎºÐ Äڵ带 º¸ÀÚ.
<¸®½ºÆ® 6> ÀÌÁß °Ë»ç Àá±Ý ÄÚµå
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null) {
helper = new Helper();
}
}
}
return helper;
}
// other functions and members...
}
¾ð¶æ º¸±â¿¡´Â È®½ÇÇÑ ¹æ¹ýÀ¸·Î º¸ÀδÙ. ¾Æ¸¶µµ ÀÌ ¹æ¹ýÀ» »ç¿ëÇÑ °³¹ßÀÚµµ ¸¹À¸¸®¶ó »ý°¢µÈ´Ù. ÇÏÁö¸¸ ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨Àº ÀÌ°ÍÀÇ Á¤»óÀûÀÎ ¼öÇàÀ» º¸ÀåÇÏÁö ¸øÇÑ´Ù.
¸ÕÀú helper = new Helper()¶ó´Â ¹®ÀåÀ» ¼öÇàÇÒ ¶§ ÄÄÆÄÀÏ·¯ÀÇ ÃÖÀûÈ¿¡ ÀÇÇØ HelperÀÇ »ý¼ºÀÚ¸¦ ¼öÇàÇÏ´Â µ¿¾È¿¡ helper Çʵ忡 °´Ã¼¸¦ ´ëÀÔÇÏ´Â °æ¿ì°¡ ÀÖÀ» ¼ö ÀÖ´Ù. Áï, Helper¶ó´Â °´Ã¼°¡ »ý¼ºµÇ´Â °úÁ¤Àº ¸ÕÀú ¸Þ¸ð¸® Èü¿¡¼ °´Ã¼ÀÇ °ø°£ÀÌ ÇÒ´çµÇ°í ±âº»°ªµé·Î ä¿öÁø ´ÙÀ½, »ý¼ºÀÚÀÇ ¸öü ÄÚµåµéÀ» ¼öÇàÇÏ°Ô µÇ´Âµ¥, ½ÇÁ¦ ¸öü Äڵ尡 ¼öÇàµÇ±â Àü¿¡ helper Çʵå·Î ´ëÀԵǴ ¼ø¼ º¯°æÀ» ÄÄÆÄÀÏ·¯°¡ ½ÃµµÇÒ ¼ö ÀÖ´Ù. ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨Àº ÄÄÆÄÀÏ·¯ÀÇ ÃÖÀûÈ¿¡ °ü·ÃµÈ ÀÌ·¯ÇÑ ¼ø¼ º¯°æÀ» Çã¿ëÇÑ´Ù. ¶Ç, ÄÄÆÄÀÏ·¯°¡ º¯°æÇÏÁö ¾ÊÀº °æ¿ì¿¡µµ ¼öÇàÇÏ´Â ÇÁ·Î¼¼¼³ª ¸Þ¸ð¸® ½Ã½ºÅÛ¿¡ µû¶ó¼ ÀÌ ¼ø¼°¡ º¯°æµÉ ¼ö ÀÖ´Ù.
ÀÌ¿¡ ´ëÇÑ ÇØ°áÃ¥À¸·Î Á¦¾ÈµÇ°í ÀÖ´Â °ÍÀº ´ÙÀ½°ú °°Àº ¹æ¹ýµéÀÌ ÀÖ´Ù.
¸ÕÀú Helper °´Ã¼¸¦ »ý¼ºÇÏ´Â ºÎºÐÀº º°µµÀÇ Å¬·¡½º¿¡¼ static Çʵå·Î ¼±¾ðÇÏ´Â ¹æ¹ýÀÌ´Ù. ÀÌ·¸°Ô µÇ¸é static Çʵ忡 Á¢±ÙÇÏ·Á°í ÇÏ´Â ¼ø°£¿¡ ÇØ´ç °´Ã¼°¡ »ý¼ºµÉ °ÍÀÌ´Ù.
class HelperSingleton {
static Helper singleton = new Helper();
}
´Ù¸¥ ¸î °¡Áö ¹æ¹ýµµ Á¦¾ÈµÇ°í ÀÖÀ¸³ª ThreadLocal µîÀ» »ç¿ëÇÏ´Â ¹æ¹ýÀº ±¸Çö °¡´ÉÇϳª ¼º´É ¸é¿¡¼ ¿ÀÈ÷·Á µ¿±âÈ ºí·ÏÀ» ¹Ù·Î »ç¿ëÇÏ´Â getHelper() ¹öÀüº¸´Ù ´õ ³ª»Ú±â ¶§¹®¿¡ ±ÇÀåµÇÁö ¾Ê´Â´Ù.
¶Ç ÇϳªÀÇ ¹æ¹ýÀº ÀÚ¹Ù 2 SDK 1.5¿¡ »õ·Î Ãß°¡µÈ ¹æ¹ýÀÌ´Ù.
Áï, volatile º¯¼ö¿Í °°Àº °³³äÀ» °´Ã¼ ÂüÁ¶¿¡±îÁö È®ÀåÇÏ´Â java.util.concurrent.atomic ÆÐÅ°ÁöÀÇ AtomicReference Ŭ·¡½º¸¦ È°¿ëÇÏ´Â ¹æ¹ýÀÌ´Ù. Âü°í·Î »ç¿ëµÈ ÄÚµå´Â ÀÚ¹Ù 2 SDK 1.5 º£Å¸2ÆÇÀ̹ǷΠÁ¤½Ä ¸±¸®½º¿¡¼´Â API°¡ º¯°æµÉ °¡´É¼ºµµ ÀÖ´Ù.
<¸®½ºÆ® 7> ÀÌÁß °Ë»ç Àá±Ý ±¸Çö
private AtomicReference<Helper> helper = new AtomicReference<Helper>();
public Helper getHelper() {
if (helper.get() == null) {
helper.compareAndSet(null, new Helper());
}
return helper.get();
}
SDK 1.5ÀÇ »õ·Î¿î µ¿±âÈ ±¸Á¶
µ¿±âÈ ±¸Á¶¿Í Doug Lea
ÀÚ¹Ù´Â °¡»ó ¸Ó½ÅÀ» ÇÊ¿ä·Î ÇÏ°í, ¶Ç °¡»ó ¸Ó½ÅÀ» ºÎÆ®½ºÆ®·¦ÇÏ´Â µ¥ »ó´çÇÑ ½Ã°£°ú ¸Þ¸ð¸® ¸®¼Ò½º°¡ ¼Ò¿äµÇ±â ¶§¹®¿¡ ¿©·¯ °³ÀÇ ÀÚ¹Ù ÇÁ·Î¼¼½º¸¦ »ç¿ëÇÏ¿© ÇÁ·Î¼¼½º °£ Åë½ÅÀ» ÇÏ´Â ÇÁ·Î±×·¥À» ÀÛ¼ºÇÏ´Â °ÍÀº ¸¹Àº °æ¿ì ÇÇÇØ¾ß ÇÑ´Ù. ÀÌ·¯ÇÑ ÀÚ¹ÙÀÇ Æ¯¼ºÀº ¾²·¹µå ±â¹ÝÀÇ ÇÁ·Î±×·¥ ±¸Á¶¸¦ ´õ¿í Áß¿äÇÏ°Ô ¸¸µå´Âµ¥, ¾²·¹µå¸¦ »ç¿ëÇÏ¿© ¿©·¯ °´Ã¼ °£ÀÇ Åë½ÅÀ̳ª ÀÚ¿ø °øÀ¯°¡ ÇÊ¿äÇÒ °æ¿ì, ÀüüÀûÀÎ ¾²·¹µå°£ ±¸Á¶¸¦ ¸ÕÀú Àß Á¤ÀÇÇÏ´Â °ÍÀÌ ºÒÇÊ¿äÇÑ, ȤÀº À߸øµÈ Àá±Ý ±¸Á¶¿Í °æÀï Á¶°Ç¿¡ ´ëÇÑ ¾î·Á¿òÀ» ´õ´Â À¯ÀÏÇÑ ¹æ¹ýÀÌ´Ù.
¾²·¹µå ¸ðµ¨À» ±¸ÇöÇÒ ¶§, ȤÀº °æÀï Á¶°Ç°ú µ¿±âÈ ¹®Á¦¸¦ ÇØ°áÇÏ°íÀÚ ÇÒ ¶§ °ËÁõµÈ µ¿±âÈ ±¸Á¶¸¦ È°¿ëÇÏ´Â °ÍÀº È¿À²ÀûÀÏ »Ó ¾Æ´Ï¶ó, ¹ö±×¸¦ ¹æÁöÇÒ ¼ö ÀÖ°í, Àüü ¾ÆÅ°ÅØó¸¦ °³¼±ÇÏ´Â È¿°ú¸¦ °¡Á®¿Â´Ù.
ÀÚ¹ÙÀÇ ¿©·¯ °¡Áö µ¿±âÈ ±¸Á¶¸¦ À̾߱âÇÒ ¶§, Doug Lea¶ó´Â »ç¶÷¿¡ ´ëÇÑ ¼Ò°³¸¦ »©³õÀ» ¼ö ¾ø´Ù. Doug Lea´Â ÀÚ¹ÙÀÇ ¾Æ¹öÁö¶ó°í ºÒ¸®´Â James Gosling°ú ´õºÒ¾î ÀÚ¹Ù ¸í¼¼¸¦ Á¤ÇÏ´Â JSRÀÇ Ãʱ⠽ÃÀý¿¡ °³ÀÎ ÀÚ°ÝÀ¸·Î ÅõÇ¥±ÇÀ» Çà»çÇÒ ¼ö ÀÖ¾ú´ø ´Ü µÎ ¸í Áß ÇÑ ¸íÀ¸·Î, ÇöÀç´Â JSR 166¹ø¿¡¼ ÀÚ½ÅÀÌ ¸¸µç °ø°³ ¼Ò½º µ¿±âÈ °ü·Ã Ŭ·¡½ºµéÀ» ÀÚ¹ÙÀÇ Ç¥ÁØÀ¸·Î SDK 1.5¿¡ Æ÷ÇÔ½ÃÅ°´Â ÀÛ¾÷À» ÇÏ°í ÀÖ´Ù.
±×ÀÇ ³ë·ÂÀ¸·Î SDK 1.5¿¡´Â ÈǸ¢ÇÑ ¾²·¹µå µ¿±âÈ ±¸Á¶ Ŭ·¡½ºµéÀÇ ÁýÇÕÀÎ java.util.concurrent ÆÐÅ°Áö°¡ Æ÷ÇԵǾú°í, À̵é API¿¡ ´ëÇÑ ÀÚ¹Ù °¡»ó ¸Ó½Å Â÷¿ø¿¡¼ÀÇ ÃÖÀûÈ ¶ÇÇÑ ÁøÇàµÇ¾ú´Ù.
ÈçÈ÷ SDK 1.5¸¦ À̾߱âÇÏ¸é ¸î °¡Áö ¾ð¾î ¹®¹ý Â÷¿øÀÇ º¯È¿Í ¸ÞŸÁ¤º¸ ó¸® ±â´É(Annotations), ÅÛÇø´(Generics) µîÀ» ¶°¿Ã¸®Áö¸¸, ÀÌ µ¿±âÈ °ü·Ã ÆÐÅ°Áö ¶ÇÇÑ Ä¿´Ù¶õ º¯ÈÀÌ°í, ¶Ç ÀÚÁÖ »ç¿ëÇÏ°Ô µÉ °ÍÀÌ´Ù.
java.util.concurrent ÆÐÅ°Áö
java.util.concurrent °ü·Ã ÆÐÅ°Áö¿¡´Â ¸¹ÀÌ »ç¿ëµÇ´Â µ¿±âÈ ±¸Á¶µé, Àá±Ý, Å¥, ¾²·¹µå Ç®, ±×¸®°í µ¿±âÈ¿¡ »ç¿ëµÇ´Â »õ·Î¿î ½Ã°£ ´ÜÀ§ Ŭ·¡½ºµéÀÌ Á¤ÀǵǾî ÀÖ´Ù.
À̵é Áß ÀÚÁÖ »ç¿ëµÉ ±¸Á¶µé¿¡ ´ëÇØ °£´ÜÇÏ°Ô ¼Ò°³¸¦ ÇÏ°íÀÚ ÇÑ´Ù.
(1) Executor¿Í Future
Executor ÀÎÅÍÆäÀ̽º´Â ¾²·¹µå¸¦ ½ÇÇà½ÃÅ°´Â »õ·Î¿î ¹æ¹ýÀ» Á¤ÀÇÇÏ°í ÀÖ´Ù. Thread Ŭ·¡½ºÀÇ start() ¸Þ¼Òµå¸¦ È£ÃâÇÏ´Â ´ë½Å Á»´õ Á÷°üÀûÀ¸·Î RunnableÀ» ½ÇÇà½ÃÅ°°Å³ª CallableÀ» ½ÇÇà½ÃŲ´Ù.
CallableÀº Runnable°ú À¯»çÇϳª ¸®ÅÏ°ªÀ» °¡Áú ¼ö ÀÖÀ¸¸ç ¿¹¿Ü¸¦ ´øÁú ¼ö ÀÖ´Ù.
Future ÀÎÅÍÆäÀ̽º´Â ºñµ¿±âÀûÀ¸·Î ¾²·¹µå¸¦ ¼öÇàÇÏ°í ´Ù¸¥ ÀÏÀ» ¼öÇàÇÑ ÈÄ, ³ªÁß¿¡ ±× °á°ú°ªÀ» °¡Á®¿Ã ¼ö ÀÖ´Â ±¸Á¶ÀÌ´Ù.
´ÙÀ½ ¿¹Á¦´Â ½ÇÁ¦ »ç¿ëÇÏ´Â ¹æ¹ýÀ» Àá±ñ º¸¿©ÁØ´Ù. SDK 1.5ÀÇ Generics°¡ »ç¿ëµÇ¾î Äڵ尡 Á¶±Ý ¾î»öÇغ¸ÀÏ °ÍÀÌ´Ù. Executor ±¸Çö °´Ã¼¸¦ ¸¸µé¾îÁÖ´Â Executors Ŭ·¡½ºÀÇ ÆÑÅ丮 ¸Þ¼Òµå¸¦ »ç¿ëÇÏ¿© ExecutorService °´Ã¼¸¦ »ý¼ºÇÏ°í, Future ÀÎÅÍÆäÀ̽º ±¸Çö Ŭ·¡½ºÀÎ FutureTask Ŭ·¡½º¸¦ »ç¿ëÇÏ¿© Future°¡ CallableÀ» ¼öÇàÇÏ°í ±× °á°ú¸¦ °¡Áö°í ÀÖµµ·Ï ÇÏ¿´´Ù.
<¸®½ºÆ® 8> Executor¿Í Future »ç¿ë ¿¹Á¦
public static void main(String[] args) throws Exception {
FutureTask<String> future = new FutureTask<String>(new Callable<String>() {
public String call() throws InterruptedException {
Thread.sleep(1000); // ¹º°¡ º¹ÀâÇÑ ÀÏÀ» ÇÑ´Ù.
return "Done";
}
});
ExecutorService executor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 3; i++) {
// future¸¦ ½ÇÇàÇÑ´Ù.
executor.execute(future);
// ¿©±â¿¡¼ ´Ù¸¥ ÀÏÀ» ¸ÕÀú ¼öÇàÇÑ´Ù.
Thread.sleep(1000);
// future¿¡ ´ã±ä °á°ú¸¦ °¡Á®¿Â´Ù. ¾ÆÁ÷ futureÀÇ ½ÇÇàÀÌ Á¾·áµÇÁö ¾ÊÀº °æ¿ì ºí·ÏµÈ´Ù.
System.out.println("Callable returned : " + future.get());
}
// executor ¼ºñ½º¸¦ Á¾·áÇÑ´Ù.
executor.shutdown();
}
(2) ¾²·¹µå Ç®
¾²·¹µå Ç®Àº ¼ºí¸´ ¼¹ö, EJB ¼¹ö µîÀÇ ±¸Çö¿¡ Á¾Á¾ »ç¿ëµÇ´Â ±¸Á¶ÀÌ´Ù. ÁÖÀÎ/ÀÏ²Û ¸ðµ¨(boss/worker model, master/slave model)¿¡¼ ¸¹ÀÌ »ç¿ëµÇ´Âµ¥, ÀÌ ÇüÅÂÀÇ ¾²·¹µå ¸ðµ¨¿¡¼ ÁÖÀÎ ¾²·¹µå´Â ¾²·¹µå Ç®¿¡¼ ½¬°í ÀÖ´Â ÀÏ²Û ¾²·¹µå¸¦ °ñ¶ó ÀÛ¾÷À» ³Ñ°ÜÁØ´Ù.
¾²·¹µå Ç® ¿ª½Ã Executors Ŭ·¡½ºÀÇ ÆÑÅ丮 ¸Þ¼Òµå¸¦ »ç¿ëÇÏ¿© ´ÙÀ½°ú °°ÀÌ Executoró·³ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
ExecutorService executor = Executors.newCachedThreadPool();
Áö¿øÇÏ´Â ¾²·¹µå Ç®Àº Àç»ç¿ëµÇ°í ÇÊ¿äÇÒ °æ¿ì »ý¼ºÇÏ´Â ¹æ½ÄÀÇ Ä³½Ã ¾²·¹µå Ç®, °íÁ¤ Å©±â ¾²·¹µå Ç®, ¾²·¹µå ½ÇÇàÀ» ½ºÄÉÁÙÇÒ ¼ö ÀÖ´Â ½ºÄÉÁÙ¸µ ¾²·¹µå Ç® µîÀÌ ÀÖ´Ù.
(3) Å¥ Ŭ·¡½ºµé
Collection Ŭ·¡½ºÀÇ Çϳª·Î Queue ÀÎÅÍÆäÀ̽º¸¦ java.util ÆÐÅ°Áö¿¡ Æ÷ÇÔ½ÃÅ°¸é¼ µ¿±âÈ ÆÐÅ°Áö¿¡´Â ¸î °¡Áö Á¾·ùÀÇ Å¥µéÀÌ Áö¿øµÈ´Ù.
Å¥´Â °¡Àå ¸¹ÀÌ »ç¿ëµÇ´Â µ¿±âÈ ±¸Á¶ Áß Çϳª·Î ¿ëµµ¿¡ µû¶ó Á¶±Ý¾¿ ´Ù¸¥ ¹öÀüÀ» »ç¿ëÇÑ´Ù.
¿¹¸¦ µé¾î »ý»êÀÚ/¼ÒºñÀÚ ¾²·¹µå ¸ðµ¨(producer/consumer model)¿¡¼ ¸¹ÀÌ »ç¿ëµÇ´Â ºí·ÎÅ· Å¥ ±¸Á¶¸¦ ±¸ÇöÇÑ BlockingQueue ÀÎÅÍÆäÀ̽º°¡ ÀÖÀ¸¸ç, Å©±â Á¦ÇÑ ¾ø´Â ³Íºí·ÎÅ· Å¥ÀÎ ConcurrentLinkedQueue Ŭ·¡½º µîÀÌ ÀÖ´Ù.
BlockingQueue ÀÎÅÍÆäÀ̽º¸¦ ±¸ÇöÇÑ ¿©·¯ °³ÀÇ ºí·ÎÅ· Å¥ ±¸Çö Ŭ·¡½ºµéÀº ´Ù¸¥ Ä÷º¼Ç ±¸Çö Ŭ·¡½º¿Í ¸¶Âù°¡Áö·Î »ç¿ëó¿¡ µû¶ó Á»´õ ÀûÇÕÇÑ ¾Ë°í¸®ÁòÀ» °ñ¶ó¼ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
(4) Lock°ú Condition
Lock ÀÎÅÍÆäÀ̽º´Â ÀÚ¹ÙÀÇ µ¿±âÈ ºí·Ï Ç¥Çö ¹æ½ÄÀÎ synchronized ºí·Ï ´ë½Å¿¡ ¸í½ÃÀûÀÎ Àá±Ý ȹµæ°ú Àá±Ý ÇØÁ¦¸¦ »ç¿ëÇÏ´Â ¹æ½ÄÀÌ´Ù. C/C++¿¡¼ Á¦°øÇÏ´Â Àá±Ý ¹æ½Ä°ú À¯»çÇÑ ¹æ½ÄÀ¸·Î ÄÚµå Â÷¿ø¿¡¼ Àá±ÝÀ» ¹Ýµå½Ã Ç®¾îÁà¾ß ÇÑ´Ù´Â Á¦¾àÀÌ ÀÖÁö¸¸, ºí·Ï ±¸Á¶°¡ ¾Æ´Ñ ¹æ½Ä, Áï ÇÊ¿ä¿¡ µû¶ó Àá±Ý ȹµæ°ú Àá±Ý ÇØÁ¦°¡ ¿ÏÀüÈ÷ ´Ù¸¥ ¸Þ¼Òµå³ª ºí·Ï¿¡¼ ó¸®µÉ ¼öµµ ÀÖÀ¸¸ç, Àá±ÝÀ» ȹµæÇÒ ¶§ tryLock()À» »ç¿ëÇÒ ¼ö ÀÖ´Ù´Â ÀåÁ¡ÀÌ ÀÖ´Ù.
Condition ÀÎÅÍÆäÀ̽º´Â ÀÚ¹ÙÀÇ µ¿±âÈ À̺¥Æ® Ç¥Çö ¹æ½ÄÀÎ wait(), notify() ¸Þ¼Òµå¿¡ ´ëÀÀÇÏ´Â °³³äÀ¸·Î wait(), notify() ¸Þ¼ÒµåµéÀÌ ´ëÀÀÇÏ´Â synchronized ºí·Ï ¾È¿¡¼ µ¿ÀÛÇϵíÀÌ Condition °´Ã¼´Â ´ëÀÀÇÏ´Â Lock °´Ã¼¸¦ ÅëÇØ µ¿ÀÛÇÑ´Ù. Condition °´Ã¼¸¦ »ç¿ëÇÒ ¶§ÀÇ ÀåÁ¡À¸·Î´Â ÇϳªÀÇ Lock °´Ã¼¿¡¼ ¿©·¯ °³ÀÇ Condition °´Ã¼¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù´Â Á¡À» µé ¼ö ÀÖ´Ù.
(5) Semaphore Ŭ·¡½º
¼¼¸¶Æ÷¾î ¿ª½Ã ¸¹ÀÌ »ç¿ëµÇ´Â µ¿±âÈ ±¸Á¶ Áß ÇϳªÀÌ´Ù.
¼¼¸¶Æ÷¾î´Â ³»ºÎÀûÀ¸·Î ¼ýÀÚ°ªÀ» À¯ÁöÇÏ°í Àִµ¥ ÀÌ °ªÀº ¾ó¸¶µçÁö Ä¿Áú ¼ö ÀÖÁö¸¸ 0º¸´Ù ÀÛÀ» ¼ö´Â ¾ø´Ù.
¼¼¸¶Æ÷¾î´Â acquire¿Í release µÎ °³ÀÇ ¿¬»êÀ» Áö¿øÇϸç, acquire ½Ã¿¡´Â ¼ýÀÚ°ªÀ» 1 °¨¼Ò½ÃÅ°°í, release ½Ã¿¡´Â ¼ýÀÚ°ªÀ» 1 Áõ°¡½ÃÅ°µÇ, ¼ýÀÚ°ªÀÌ 0ÀÌ µÇ¸é, acquire¸¦ ¿äûÇÑ ¾²·¹µå°¡ ¹«ÇÑÈ÷ ±â´Ù¸®µµ·Ï ÇÏ´Â ¹æ½ÄÀ¸·Î µ¿ÀÛÇÑ´Ù.
ÀÌ·¸°Ô ÇÔÀ¸·Î½á °á°úÀûÀ¸·Î µ¿½Ã¿¡ Á¢±ÙÇÏ´Â ¾²·¹µåÀÇ °¹¼ö¸¦ ÁöÁ¤ÇÑ ¼ýÀÚ°ªÀ¸·Î Á¦ÇÑÇÏ°Ô µÈ´Ù.
(6) ReadWriteLock Ŭ·¡½º
ÇÁ·Î±×·¥¿¡ µû¶ó ¿©·¯ °³ÀÇ ¾²·¹µåµéÀÌ °øÀ¯ÇÏ´Â µ¥ÀÌÅ͸¦ Àд Ƚ¼ö°¡ ¾²´Â Ƚ¼öº¸´Ù ÈξÀ ¸¹Àº °æ¿ì°¡ ÀÖ´Ù. ÀÌ·± °æ¿ì ¿©·¯ °³ÀÇ ¾²·¹µå°¡ µ¿½Ã¿¡ ÀÐÀ» ¼ö ÀÖµµ·Ï Çã¿ëÇÏ°í, ¾µ °æ¿ì¿¡´Â ¹èŸÀûÀ¸·Î Á¢±ÙÀ» ¸·´Â ¹æ½ÄÀÇ Àá±Ý ±¸Á¶°¡ ´Ü¼øÇÑ Àá±Ý ±¸Á¶¿¡ ºñÇØ ÈξÀ È¿À²ÀûÀÏ ¼ö ÀÖ´Ù. Áï, ºó¹øÇÏ°Ô ÀϾ´Â ÀбâÀÇ °æ¿ì¿¡´Â ¿©·¯ °³ÀÇ ¾²·¹µåµéÀÌ Àá±ÝÀÌ ÇÊ¿ä¾øÀÌ Á¢±ÙÇÒ ¼ö ÀÖÀ¸¹Ç·Î, Àá±ÝÀÇ ¿À¹öÇìµå¸¦ ÇÇÇÒ ¼ö°¡ ÀÖ´Ù. ƯÈ÷ Àд µ¿ÀÛÀÌ ±ä °æ¿ì¿¡´Â ´õ¿í È¿À²ÀûÀÌ´Ù.
Àбâ/¾²±â Àá±Ý ±¸Á¶¿¡¼ ¸¸¾à ¾²±â ¾²·¹µå°¡ ¿¹»óÇÑ ºñÀ²º¸´Ù ´õ ¸¹ÀÌ Á¢±ÙÇÒ °æ¿ì ¾²±â ¾²·¹µå°¡ Àá±ÝÀ» ¾Æ¿¹ ¾òÁö ¸øÇÒ ¼öµµ ÀÖ´Ù. ÀÌ·± °æ¿ì¸¦ ÈçÈ÷ ±â¾Æ »óÅÂ(starvation)¶ó°í ºÎ¸¥´Ù.
Àбâ/¾²±â Àá±Ý ±¸Á¶¿¡¼ Àá±Ý ´Ù¿î±×·¹ÀÌµå °³³äÀÌ Áö¿øµÇ´Âµ¥, ÀÌ°ÍÀº ¾²±â Àá±ÝÀ» °¡Áø ¾²·¹µå°¡ Àбâ Àá±ÝÀ» ¾òÀº ´ÙÀ½, ¾²±â Àá±ÝÀ» Ç®¾î °á°úÀûÀ¸·Î Àбâ Àá±ÝÀ¸·Î ´Ù¿î±×·¹À̵åÇÏ´Â °³³äÀÌ´Ù. Àбâ Àá±ÝÀ» °¡Áø ¾²·¹µå´Â Àý´ë ¾²±â Àá±ÝÀ» ȹµæÇÒ ¼ö ¾ø´Ù. Áï, ¾²±â Àá±ÝÀ¸·Î ¾÷±×·¹À̵åÇÒ ¼ö´Â ¾ø´Ù.
(7) CyclicBarrier Ŭ·¡½º
¹æº® ±¸Á¶(Barrier)´Â ¿©·¯ ¾²·¹µåµéÀÌ ¼·ÎÀÇ ¼öÇàÀ» µ¿±âÈÇϱâ À§ÇØ ±â´Ù¸®´Â µ¿±âÈ ÁöÁ¡À» ³ªÅ¸³»´Â ±¸Á¶ÀÌ´Ù.
¼·Î Çù¾÷ÇÏ´Â ¾²·¹µåµéÀÌ ¸ðµÎ ¹æº® ÁöÁ¡¿¡ À̸¦ ¶§±îÁö ±â´Ù·È´Ù°¡, ¸ðµÎ µµÂøÇÏ¸é ´ÙÀ½ ´Ü°è·Î ³Ñ¾î°¡´Â ¹æ½ÄÀ¸·Î ÁøÇàµÈ´Ù. Áï, ¸¶Áö¸· ¾²·¹µå°¡ ¹æº® ÁöÁ¡¿¡ µµÂøÇÒ ¶§±îÁö ¸ÕÀú ¿Â ¾²·¹µåµéÀº ±â´Ù¸®°í ÀÖ´Ù°¡ µµÂøÇÏ´Â ¼ø°£ ¸ðµÎ ´Ù½Ã ÁøÇàÀ» °è¼ÓÇÑ´Ù. Áï, ÀÏÁ¤ °³¼öÀÇ ¾²·¹µå°¡ µµ´ÞÇÒ ¶§±îÁö ¹æº®ÀÌ °¢ ¾²·¹µåÀÇ ÁøÇàÀ» ¸·°í ÀÖ´Ù°¡, ÀÏÁ¤ °³¼öÀÇ ¾²·¹µå°¡ µµ´ÞÇÏ´Â ¼ø°£ µµ´ÞÇÑ ¾²·¹µåµéÀ» ¸ðµÎ ¹æº®À» Áö³ª°¡µµ·Ï Åë°ú½ÃÅ°´Â ±¸Á¶ÀÌ´Ù.
ÀÌ ±¸Á¶´Â ¼±¿ø ¸ðµ¨(work crew model ȤÀº divide and conquer model)À» ±¸ÇöÇÏ´Â µ¥ ¸¹ÀÌ »ç¿ëµÈ´Ù.
¼±¿ø ¸ðµ¨¿¡¼´Â ÇϳªÀÇ ÀÛ¾÷À» ¿©·¯ Á¶°¢ÀÇ ºÎºÐ ÀÛ¾÷À¸·Î ³ª´©¾î ¿©·¯ °³ÀÇ ¾²·¹µå°¡ ÇÑ Á¶°¢¾¿ µ¿½Ã¿¡ ¼öÇàÇÏ´Â ¹æ½ÄÀ¸·Î ÀÛ¾÷À» ¼öÇàÇÑ´Ù. °¢ ¾²·¹µå´Â ´Ù¸¥ ¾²·¹µåÀÇ ÀÛ¾÷ ÁøÇà »óÅ¿¡ ÀÇÁ¸ÇÏÁö ¾Ê°í, µ¶ÀÚÀûÀ¸·Î ÀÛ¾÷À» ÁøÇàÇÑ´Ù.
¼±¿ø ¸ðµ¨ÀÇ ¿¹´Â ¾î¶² ¿µ¿ª¿¡ °ÉÃÄ ÀڷḦ °Ë»öÇÏ´Â ÀÛ¾÷ÀÌ ÀÖÀ» ¶§ ¿µ¿ªÀ» ºÐ¸®ÇÏ¿© °¢ ¿µ¿ªº°·Î ¼±¿ø ¾²·¹µå¸¦ ¸¸µé¾î °Ë»öÇÏ´Â °ÍÀ» »ý°¢Çغ¼ ¼ö ÀÖ´Ù. °¢ ºÎºÐ ¿µ¿ªÀ» ¸Ã°í ÀÖ´Â ¾²·¹µåµéÀÌ ¸ðµÎ ÀÛ¾÷À» ¿Ï·áÇÏ¸é ºÎºÐ ÀÛ¾÷ °á°úµéÀ» ÅëÇÕÇÏ¿© Àüü ÀÛ¾÷ °á°ú°¡ ³ª¿Â´Ù.
ÀϹÝÀûÀ¸·Î ¼±¿ø ¸ðµ¨À» »ç¿ëÇÒ °æ¿ì °¢ ¼±¿ø ¾²·¹µåº°·Î Á¾·á ½Ã°£ÀÌ ´Ù¸£¹Ç·Î, ¸ðµç ¼±¿ø ¾²·¹µå°¡ Á¾·áÇÑ ÈÄ °¢ °á°ú¹°µéÀ» Á¾ÇÕÇÏ´Â ¹æ½ÄÀ¸·Î ÁøÇàÇÏ°Ô µÈ´Ù.
CyclicBarrier Ŭ·¡½º´Â ¹æº® ±¸Á¶¸¦ Àß ±¸ÇöÇÑ Å¬·¡½º·Î, µµ´ÞÇÑ °¢ ¾²·¹µå´Â CyclicBarrier °´Ã¼ÀÇ await() ¸Þ¼Òµå¸¦ È£ÃâÇÏ°í, ÁöÁ¤µÈ Á¤¿øÀÌ Âû ¶§±îÁö ºí·ÎÅ·µÈ´Ù. Á¤¿øÀÌ Â÷°í ³ ´ÙÀ½¿¡´Â CyclicBarrier °´Ã¼¸¦ »ý¼ºÇÒ ¶§ Runnable °´Ã¼°¡ ÁöÁ¤ÇÑ °æ¿ì ÀÌ °´Ã¼¸¦ ½ÇÇàÇÏ¿© °á°ú¹°µéÀ» Á¾ÇÕÇÏ´Â °³³äÀÇ ÀÏÀ» ÇÒ ¼ö ÀÖ´Ù. CyclicBarrier °´Ã¼´Â ÀÌ RunnableÀ» ¼öÇàÇÑ ÈÄ ºí·ÎÅ·µÇ¾ú´ø ¸ðµç ¾²·¹µåµéÀ» Ç®¾îÁØ´Ù.
(8) CountDownLatch Ŭ·¡½º
CountDownLatch Ŭ·¡½º´Â CyclicBarrier Ŭ·¡½º¿Í À¯»çÇÏ°Ô ÇØ´ç °´Ã¼¿¡ ´ëÇØ await() ¸Þ¼Òµå¸¦ È£ÃâÇϸé Á¶°ÇÀÌ ÃæÁ·µÉ ¶§±îÁö ºí·ÎÅ·µÇÁö¸¸, CyclicBarrier°¡ await()¸¦ È£ÃâÇÑ ¾²·¹µåÀÇ °¹¼ö¿¡ µû¶ó ºí·ÎÅ·À» Ç®¾îÁÖ´Â ¹Ý¸é, CountDownLatch´Â countDown() ¸Þ¼Òµå°¡ È£ÃâµÇ´Â Ƚ¼ö¿¡ µû¶ó ºí·ÎÅ·À» Ç®¾îÁÖ°Ô µÈ´Ù´Â Á¡ÀÌ´Ù.
¶Ç, CyclicBarrier °´Ã¼´Â reset() ¸Þ¼Òµå¸¦ Á¦°øÇÏ¿© ´Ù½Ã »ç¿ëÇÒ ¼ö ÀÖÁö¸¸, CountDownLatch °´Ã¼´Â Çѹø¸¸ »ç¿ë °¡´ÉÇÏ´Ù.
(8) Exchanger Ŭ·¡½º
Exchanger Ŭ·¡½º´Â µÎ °³ÀÇ ¾²·¹µå°¡ ƯÁ¤ ÁöÁ¡¿¡¼ µ¿ÀÏÇÑ ÀÚ·áÇüÀÇ µ¥ÀÌÅ͸¦ ¼·Î ±³È¯ÇÒ ¼ö Àִ Ưº°ÇÑ µ¿±âÈ ±¸Á¶ÀÌ´Ù. µÎ °³ÀÇ ¾²·¹µå°¡ µ¿ÀÏÇÑ Exchanger °´Ã¼¿¡ ´ëÇØ exchange() ¸Þ¼Òµå¸¦ È£ÃâÇϸé, µÎ ¾²·¹µå°¡ ¸ðµÎ È£ÃâÇÒ ¶§±îÁö ºí·ÎÅ·µÇ¾ú´Ù°¡ ¼·ÎÀÇ °ªÀ» ±³È¯ÇÑ ÈÄ °è¼ÓÇؼ ¾²·¹µå°¡ ÁøÇàÇÏ°Ô µÈ´Ù.
¾²·¹µå, µ¿±âÈ, µ¥µå¶ô, ...
¾ó¸¶ Àü, µ¥µå¶ô ¹®Á¦ ÇØ°áÀ» ¿äû ¹Þ¾Æ ¼Ò½º Äڵ带 »ìÆ캸´Ï, ¹®Á¦ÀÇ ¿øÀÎÀº µ¿±âÈµÈ ¸Þ¼ÒµåÀÇ ¸®ÅÏ°ªÀ» ºñ±³ÇÏ´Â ¼ø°£¿¡ Àӽà º¯¼ö·Î ÀúÀåµÇ´Â ¹®Á¦¿´¾ú´Ù.
Áï, ´ÙÀ½ Äڵ忡¼ getValue() ¸Þ¼Òµå´Â µ¿±âȵǾî ÀÖÁö¸¸, ±× °á°ú°ªÀ» 0°ú ºñ±³Çϱâ À§ÇØ ÇØ´ç°ªÀÌ º¸ÀÌÁö ¾Ê´Â Àӽà º¯¼ö¿¡ ÀúÀåµÇ°í 0°ú ºñ±³µÈ´Ù. ÀÌ ¹®Á¦´Â 1°³ÀÇ CPU¸¦ °¡Áø °÷¿¡¼´Â µ¥µå¶ôÀÌ °ËÃâµÇÁö ¾Ê´Ù°¡ 2°³ÀÇ CPU¸¦ °¡Áø ¼¹ö¿¡¼´Â ´ÙÇàÈ÷µµ 100¹ø¿¡ Çѵιø²Ã·Î ÁÖ±âÀûÀ¸·Î ¹ß»ýÇÏ¿´´Ù.
public synchronized int getValue() {
return value;
}
...
void someOtherClassMethod() {
synchronized(other) {
if (x.getValue() > 0) {
...
} else {
...
}
}
}
ÀÌ ¹®Á¦´Â ºñ±³ÇÏ´Â ÄÚµå ÀÚü¸¦ ÇØ´ç °´Ã¼ÀÇ µ¿±âÈ ºí·Ï ¾ÈÀ¸·Î ¿Å±â´Â ¸®ÆÑÅ丵À» ÅëÇØ ÇØ°áµÇ¾ú´Ù.
public synchronized boolean isPositive() {
return value > 0;
}
...
void someOtherClassMethod() {
synchronized(other) {
if (x.isPositive()) {
...
} else {
...
}
}
}
ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨Àº synchronized ºí·Ï°ú volatile º¯¼ö¿¡ ´ëÇØ ´ÙÁß ¾²·¹µå ȯ°æ¿¡ ÇÑÇØ Æ¯º°ÇÑ Àǹ̸¦ ºÎ¿©ÇÏ¿´°í, ±×·¸Áö ¾ÊÀº °æ¿ì´Â ´Ù¾çÇÑ ÃÖÀûÈÀÇ °¡´É¼ºÀ» ¿¾î³õ°í ÀÖ´Ù.
µ¥µå¶ô »óȲ¿¡¼ Áß¿äÇÑ °ÍÀº »óȲÀÇ ¹«¾ùº¸´Ùµµ µ¥µå¶ô ½Ã³ª¸®¿ÀÀÇ ³í¸®Àû À籸¼ºÀÌ´Ù. ÀÌ°ÍÀº ´Ù¸¥ ¹ö±×µé¿¡ ºñÇØ ¼ø¼öÇÏ°Ô ³í¸®ÀûÀ¸·Î ±¸¼ºÇØ¾ß ÇÏ´Â ºÎºÐÀÌ ¸¹±â ¶§¹®¿¡ ¾î·Æ°Ô ´À²¸Áö±âµµ ÇÑ´Ù. ÇÏÁö¸¸, ¾î·Æ´Ù°í ´Ù¸¥ ÇØ°á ¹æ¹ýÀÌ ÀÖ´Â °ÍÀÌ ¾Æ´Ï¶ó¸é, ´ÙÁß ¾²·¹µåÀÇ È¯°æÀ» ÇÊ¿ä·Î ÇÑ´Ù¸é ħÂøÇÏ°Ô ºÐ¼®ÇÏ´Â ÀÚ¼¼°¡ ÇÊ¿äÇÏ´Ù.
¾î¿ ¼ö ¾øÀÌ, ¼ö¸¹Àº Àá±ÝÀÌ ÇÊ¿äÇÑ °æ¿ì°¡ ÀÖ´Ù. ÀÌ·¯ÇÑ Àá±Ý ±¸Á¶¸¦ °³¼±ÇÏ°í, º¸´Ù ³ªÀº ¼öÇà ¼º´ÉÀ» º¸ÀåÇÏ·Á¸é º¸´Ù ÀûÇÕÇÑ µ¿±âÈ ±¸Á¶°¡ ¾ø´ÂÁö Çѹø »ìÆ캸±â ¹Ù¶õ´Ù.
ÀÚ¹Ù 2 SDK 1.5ÀÇ µ¿±âÈ ±¸Á¶µéÀº ´ëºÎºÐÀÇ °æ¿ì¿¡ Àû¿ë °¡´ÉÇÑ °ÍµéÀÌ´Ù. SDK 1.4¿¡ ´çÀå Àû¿ëÇÏ°í ½Í´Ù¸é ¸¹Àº °æ¿ì´Â ÀÌ ÆÐÅ°ÁöÀÇ ±âÁ¸ ¹öÀüÀÎ Doug LeaÀÇ util.concurrent ÆÐÅ°Áö¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
java.util.concurrent ÆÐÅ°Áö¿¡ ´ëÇØ ÃæºÐÇÑ ÄÚµå ¼öÁØÀÇ ¼Ò°³¸¦ ÇÏ°í ½Í¾úÁö¸¸, °³°ýÀûÀÎ ¼Ò°³¿¡ ±×ÃÄ ¾Æ½±´Ù.
Âü°íÀÚ·á
1 Java Language Specification, 2nd edition
http://java.sun.com/docs/books/jls/html/index.html
2 Java Specification Requests 166: Concurrency Utilities
http://jcp.org/en/jsr/detail?id=166
3 Java Specification Requests 133: Java Memory Model and Thread Specification Revision
http://jcp.org/en/jsr/detail?id=133
4 The "Double-Checked Locking is Broken" Declaration :
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
5 Concurrent Programming in Java - Design principles and patterns, 2nd Ed, Doug Lea, Addison-Wesley, 1999
6 util.concurrent package by Doug Lea
http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html
7 ÀÚ¹Ù 2 SDK 1.4 ½ÃÀÛ ±×¸®°í ¿Ï¼º, 16Àå ¾²·¹µå ÇÁ·Î±×·¡¹Ö ±â¹ý, À±°æ±¸, ´ë¸²ÃâÆÇ»ç, 2003
8 À±°æ±¸ÀÇ ÀÚ¹Ù µµ¸ÞÀÎ
http://www.javadom.com