Å×Å©´ÏÄà Ä÷³-ÀÚ¹Ù

ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨°ú ¾²·¹µå

ÀÚ¹Ù°¡ ¾ð¾î Â÷¿ø¿¡¼­ äÅÃÇÑ ´ÙÁß ¾²·¹µå ±â´ÉÀº Ãʱâ ÀÚ¹ÙÀÇ È®»ê¿¡ Å©°Ô ±â¿©ÇÏ´Â ¿äÀÎÀ̾ú´Ù. ¾ð¾î Â÷¿ø¿¡¼­ ¾²·¹µå¸¦ ½±°Ô »ý¼ºÇÏ°í °£´ÜÇÏ°Ô µ¿±âÈ­¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Â ±â´ÉÀ» Á¦°øÇϱ⠶§¹®¿¡ ´ÙÁß ¾²·¹µå´Â ÀÚ¹Ù ÇÁ·Î±×·¥ÀÇ ±âº» ¿ä±¸ »çÇ×ó·³ µÇ¾ú´Ù. ÇÏÁö¸¸, ¸ÖƼ ÇÁ·Î¼¼¼­¸¦ ÀåÂøÇÑ ÄÄÇ»Å͵éÀÇ È®»ê°ú ´õºÒ¾î ´ÙÁß ¾²·¹µå¸¦ »ç¿ëÇÑ ÇÁ·Î±×·¥¿¡¼­ ¿¹±âÄ¡ ¸øÇÑ µ¥µå¶ô »óȲÀÌ Á¾Á¾ ¹ß»ýÇÏ°í ÇÁ·Î±×·¡¸ÓµéÀº À̸¦ Á¦´ë·Î ÇØ°áÇÏÁö ¸øÇÏ´Â °æ¿ì°¡ ¸¹´Ù.

¿©±â¿¡¼­´Â ÀÚ¹ÙÀÇ ´ÙÁß ¾²·¹µå ȯ°æ¿¡¼­ ¹ß»ýÇÏ´Â ¸î °¡Áö ÀüÁ¦µé°ú ÀÚ¹Ù ¾ð¾î¿¡¼­ Á¤ÀÇÇÏ°í ÀÖ´Â ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨, ±×¸®°í À߸øµÈ µ¿±âÈ­ ±¸Á¶ÀÇ ³²¿ëÀ» ÇÇÇÏ°í ¹®¸ÆÀÌ ¿ä±¸ÇÏ´Â ÀûÀýÇÑ ±¸Á¶¸¦ »ç¿ëÇÏ´Â µ¥ Å« µµ¿òÀ» ÁÙ ÀÚ¹Ù 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