IBM Korea Skip to main content
       IBM Ȩ    |  Á¦Ç° & ¼­ºñ½º  |  °í°´Áö¿ø & ´Ù¿î·Îµå  |  È¸¿ø°¡ÀÔ  

Double-checked locking°ú Singleton ÆÐÅÏ
¸ñ Â÷:
Singleton creation À̵ð¾ö
Double-checked locking
Out-of-order write
Double-checked locking: Take two
volatile
¼Ö·ç¼Ç
½ºÆ®¸µÀº º¯ÇÏÁö ¾Ê´Â´Ù!
¿ä¾à
Âü°íÀÚ·á
ÇÊÀÚ¼Ò°³
±â»ç¿¡ ´ëÇÑ Æò°¡
°ü·Ã dW ¸µÅ©:
Threading lightly: Synchronization is not the enemy
Threading lightly: Sometimes it's best not to share
Writing multithreaded Java applications
Subscribe to the developerWorks newsletter
US ¿ø¹® Àбâ
Also in the Java zone:
Tutorials
Tools and products
Code and components
Articles
double-checked locking À̵ð¾ö ¿¬±¸


Peter Haggar
¼ÒÇÁÆ®¿þ¾î ¿£Áö´Ï¾î, IBM
2002³â 5¿ù

¸ðµç ÇÁ·Î±×·¡¹Ö ¾ð¾î¿¡´Â °íÀ¯ÀÇ À̵ð¾öÀÌ ÀÖ´Ù. ÀÌÁß ´ëºÎºÐÀÌ À¯¿ëÇÏ´Ù. ¹®Á¦´Â ¸î¸î À̵ð¾öÀÇ °æ¿ì ¿ø·¡ Ç¥¸íÇß´ø °ÍÀÌ ¾Æ´Ï¶ó´Â °ÍÀÌ ³ªÁß¿¡ ÀÔÁõµÇ°Å³ª ¼³¸íÇÑ´ë·Î ÀÛµ¿ÇÏÁö ¾Ê´Ù´Â Á¡ÀÌ´Ù. ÀÚ¹Ù¿¡´Â ¸¹Àº À¯¿ëÇÑ À̵ð¾öÀÌ ÀÖ´Ù. ÇÏÁö¸¸ °áÄÚ »ç¿ëµÇ¾î¼­´Â ¾ÈµÇ´Â À̵ð¾öµµ ÀÖ´Ù. Double-checked lockingÀÌ ¹Ù·Î ±×°ÍÀÌ´Ù. À̱ۿ¡¼­´Â double-checked locking À̵ð¾öÀÇ ±Ù¿øºÎÅÍ »ìÆ캻´Ù.

Singleton creation patternÀº ÀϹÝÀûÀÎ ÇÁ·Î±×·¡¹Ö À̵ð¾öÀÌ´Ù. ´ÙÁß ¾²·¹µå¿Í ÇÔ²² »ç¿ëÇÒ ¶§ µ¿±âÈ­ À¯ÇüÀ» »ç¿ëÇØ¾ß ÇÑ´Ù. Á»´õ È¿À²ÀûÀÎ Äڵ带 ¸¸µé±âÀ§ÇÑ ³ë·ÂÀ¸·Î ÀÚ¹Ù ÇÁ·Î±×·¡¸ÓµéÀº Äڵ尡 µ¿±âÈ­ µÇ´Â °ÍÀ» Á¦ÇÑÇϱâÀ§ÇØ Singleton creation pattern°ú ÇÔ²² ¾²ÀÏ double-checked locking À̵ð¾öÀ» ¸¸µé¾ú´Ù. ÇÏÁö¸¸ ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨¿¡ ´ëÇÑ ÀÌÇØÀÇ ºÎÁ·À¸·Î double-checked locking À̵ð¾öÀº ÀÛµ¿À» º¸ÀåÇÒ ¼ö ¾ø´Ù. °Ô´Ù°¡ ÀÛµ¿ ½ÇÆÐÀÇ ÀÌÀ¯´Â ¸íÈ®ÇÏÁö ¾Ê°í ÀÚ¹Ù ¸Þ¸ð¸® ¸ðµ¨°ú ¹ÐÁ¢ÇÏ°Ô ¿¬°üµÇ¾î ÀÖ´Ù. ¶§¹®¿¡, double-checked lockingÀ¸·Î ÀÎÇÑ ÄÚµå ÀÛµ¿ ½ÇÆÐÀÇ ¿øÀÎÀ» °Ë»çÇϱâ Èûµé´Ù. ÀÌ ±ÛÀ» ÅëÇØ ´ÜÁö ±×°ÍÀÌ ¾îµð¼­ °íÀåÀÌ ³µ´ÂÁö¸¦ ÀÌÇØÇÒ ¼ö ÀÖµµ·Ï double-checked locking À̵ð¾öÀ» ¿¬±¸Çغ»´Ù.

Singleton creation À̵ð¾ö
double-checked locking À̵ð¾öÀÌ ¾îµð¼­ ±â¿øÇß´ÂÁö¸¦ ÀÌÇØÇÏ·Á¸é ÀϹÝÀûÀÎ singleton creation À̵ð¾öÀ» ¾Ë¾Æ¾ß ÇÑ´Ù. (Listing 1):

Listing 1. Singleton creation À̵ð¾ö

import java.util.*;
class Singleton
{
  private static Singleton instance;
  private Vector v;
  private boolean inUse;

  private Singleton()
  {
    v = new Vector();
    v.addElement(new Object());
    inUse = true;
  }

  public static Singleton getInstance()
  {
    if (instance == null)          //1
      instance = new Singleton();  //2
    return instance;               //3
  }
}

ÀÌ Å¬·¡½ºÀÇ µðÀÚÀÎÀº ´ÜÁö ÇϳªÀÇ Singleton °´Ã¼°¡ ¸¸µé¾îÁ³´Ù´Â °ÍÀ» È®ÀνÃÄÑÁÖ°í ÀÖ´Ù. »ý¼ºÀÚ´Â privateÀ¸·Î ¼±¾ðµÇ°í getInstance() ¸Þ¼Òµå´Â ´ÜÁö ÇϳªÀÇ °´Ã¼¸¦ ¸¸µç´Ù. ÀÌ°ÍÀº ´ÜÀÏ ¾²·¹µå ÇÁ·Î±×·¥¿¡ ÀûÇÕÇÏ´Ù. ÇÏÁö¸¸ ´ÙÁß ¾²·¹µå°¡ °³ÀÔµÇ¸é µ¿±âÈ­¸¦ ÅëÇؼ­ getInstance() ¸Þ¼Òµå¸¦ ¹æ¾îÇØ¾ß ÇÑ´Ù. getInstance() ¸Þ¼Òµå°¡ ¹æ¾îµÇÁö ¾ÊÀ¸¸é Singleton °´Ã¼ÀÇ µÎ °³ÀÇ ´Ù¸¥ ÀνºÅÏÆ®¸¦ ¸®ÅÏÇÒ ¼ö ÀÖ´Ù. getInstance() ¸Þ¼Òµå¸¦ µ¿½Ã¿¡ È£ÃâÇÏ°í ´ÙÀ½ À̺¥Æ®¸¦ µû¶ó°¡´Â µÎ °³ÀÇ ¾²·¹µå¸¦ »ý°¢Çغ¸ÀÚ:

  1. Thread 1Àº getInstance() ¸Þ¼Òµå¸¦ È£ÃâÇÏ°í //1¿¡¼­ ±× instance°¡ nullÀ̶ó´Â °ÍÀ» °áÁ¤ÇÑ´Ù.

  2. Thread 1Àº if ºí·ÏÀ¸·Î µé¾î°¡Áö¸¸, //2ÀÇ ¶óÀÎÀ» ½ÇÇàÇϱâ Àü¿¡ thread 2¿¡ ¼±Á¡µÈ´Ù.

  3. Thread 2´Â getInstance() ¸Þ¼Òµå¸¦ È£ÃâÇÏ°í ±× instance°¡ //1¿¡¼­ null À̶ó´Â °ÍÀ» °áÁ¤ÇÑ´Ù.

  4. Thread 2´Â if ºí·ÏÀ¸·Î µé¾î°¡¼­ »õ·Î¿î Singleton °´Ã¼¸¦ ¸¸µé°í instance º¯¼ö¸¦ ÀÌ »õ·Î¿î //2¿¡ ÀÖ´Â »õ·Î¿î °´Ã¼¿¡ ÇÒ´çÇÑ´Ù.

  5. Thread 2´Â //3¿¡ ÀÖ´Â Singleton °´Ã¼ ·¹ÆÛ·±½º¸¦ ¸®ÅÏÇÑ´Ù.

  6. Thread 2´Â thread 1¿¡ ¼±Á¡µÈ´Ù.

  7. Thread 1´Â ³²°ÜÁø °÷¿¡¼­ ºÎÅÍ ½ÃÀÛÇÏ°í ´Ù¸¥ Singleton °´Ã¼°¡ ¸¸µé¾îÁö´Â °á°ú°¡ µÈ //2 ¶óÀÎÀ» ½ÇÇàÇÑ´Ù.

  8. Thread 1Àº //3¿¡¼­ ÀÌ °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù.

°á°ú´Â getInstance() ¸Þ¼Òµå°¡ ´ÜÁö ÇϳªÀÇ °´Ã¼¸¦ ¸¸µé¾î¾ß Çϴµ¥ µÎ°³ÀÇ Singleton °´Ã¼¸¦ ¸¸µé¾ú´Ù. ÀÌ ¹®Á¦´Â ´ÜÁö ÇϳªÀÇ ¾²·¹µå°¡ ÇÑ ¹ø¿¡ Äڵ带 ½ÇÇàÇϵµ·Ï getInstance() ¸Þ¼Òµå¸¦ µ¿±âÈ­½ÃÄÑ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù (Listing 2):

Listing 2. ¾²·¹µå ¹æÁö getInstance() ¸Þ¼Òµå

public static synchronized Singleton getInstance()
{
  if (instance == null)          //1
    instance = new Singleton();  //2
  return instance;               //3
}

Listing 2ÀÇ ÄÚµå´Â getInstance() ¸Þ¼Òµå·Î ¸ÖƼ¾²·¹µå ¾×¼¼½º¿¡ Àß ÀÛµ¿ÇÑ´Ù. ÇÏÁö¸¸ ÀÌ°ÍÀ» ºÐ¼®Çغ¸¸é µ¿±âÈ­´Â ¸Þ¼ÒµåÀÇ Ã¹ ¹ø° È£Ãâ¿¡¸¸ ÇÊ¿äÇÏ´Ù´Â °ÍÀ» ±ú´Ý°Ô µÈ´Ù. Áö¼ÓÀûÀΠȣÃâÀº µ¿±âÈ­¸¦ ÇÊ¿ä·ÎÇÏÁö ¾Ê´Â´Ù. ù ¹ø° È£ÃâÀÌ //2¿¡¼­ Äڵ带 ½ÇÇàÇÏ´Â À¯ÀÏÇÑ È£ÃâÀ̱⠶§¹®ÀÌ´Ù. ÀÌ ¶óÀÎÀº µ¿±âÈ­°¡ ÇÊ¿äÇÑ À¯ÀÏÇÑ ¶óÀÎÀÌ´Ù. ¸ðµç ´Ù¸¥ È£ÃâµéÀº instance°¡ nullÀÌ ¾Æ´Ï¶ó´Â °ÍÀ» °áÁ¤ÇÏ°í ÀÌ°ÍÀ» ¸®ÅÏÇÑ´Ù. ´ÙÁß ¾²·¹µå´Â ù ¹ø° °ÍÀ» Á¦¿ÜÇÏ°í´Â ¸ðµç È£Ãâ¿¡ ´ëÇØ ÀÏ°ü¼º ÀÖ°Ô ½ÇÇàÇÒ ¼ö ÀÖ´Ù. ÇÏÁö¸¸, ¸Þ¼Òµå°¡ synchronized µÉ ¶§, ¸Þ¼ÒµåÀÇ ¸ðµç È£Ãâ¿¡ ´ëÇØ µ¿±âÈ­ÀÇ ´ë°¡¸¦ ÁöºÒÇؾßÇÑ´Ù.

ÀÌ ¸Þ¼Òµå¸¦ Á»´õ È¿À²ÀûÀ¸·Î ¸¸µé±â À§Çؼ­ double-checked lockingÀ̶ó´Â À̵ð¾öÀÌ ¸¸µé¾îÁ³´Ù. ù ¹ø° °ÍÀ» Á¦¿ÜÇÑ ¸ðµç ¸Þ¼Òµå È£Ãâ¿¡ ´ëÇØ µ¿±âÈ­¸¦ ÇÇÇÏ·Á´Â »ý°¢ÀÌ´Ù. µ¿±âÈ­ÀÇ ºñ¿ëÀº JVM °ú´Â ´Ù¸£´Ù. Ãʱ⿡ ÀÌ ºñ¿ëÀº ¸Å¿ì ³ô¾Ò´Ù. Çâ»óµÈ JVMÀÌ µîÀåÇÔ¿¡ µû¶ó, µ¿±âÈ­ÀÇ ºñ¿ëÀº °¨¼ÒÇßÁö¸¸ ¿©ÀüÈ÷ synchronized ¸Þ¼Òµå ¶Ç´Â ºí·Ï¿¡ µé¾î°¡°í ³ª¿À´Â °Í¿¡ ´ëÇÑ ÆÛÆ÷¸Õ½º ÆгÎƼ´Â Á¸ÀçÇÑ´Ù. JVM ±â¼úÀÇ ¹ßÀü°ú °ü°è¾øÀÌ ÇÁ·Î±×·¡¸ÓµéÀº ºÒÇÊ¿äÇÏ°Ô ÇÁ·Î¼¼½º ½Ã°£À» ³¶ºñÇϱ⸦ °áÄÚ ¿øÇÏÁö ¾Ê´Â´Ù.

Listing 2ÀÇ //2 ÇุÀÌ µ¿±âÈ­°¡ ÇÊ¿äÇϱ⠶§¹®¿¡, ÀÌ°ÍÀ» µ¿±âÈ­ ºí·ÏÀ¸·Î ·¡ÇÎÇÑ´Ù (Listing 3):

Listing 3. getInstance() ¸Þ¼Òµå

public static Singleton getInstance()
{
  if (instance == null)
  {
    synchronized(Singleton.class) {
      instance = new Singleton();
    }
  }
  return instance;
}

Listing 3ÀÇ ÄÚµå´Â ´ÙÁß ¾²·¹µå¿¡ ³ªÅ¸³µ´ø ¹®Á¦¿Í °°´Ù. µÎ °³ÀÇ ¾²·¹µå´Â instance°¡ nullÀÌ¸é µ¿½ÃÀûÀ¸·Î if ¹® ³»ºÎ¿¡¼­ ¾ò¾îÁú ¼ö ÀÖ´Ù. ±×¸®°í³ª¼­ ÇϳªÀÇ ¾²·¹µå°¡ instance¸¦ ÃʱâÈ­Çϱâ À§Çؼ­ synchronized ºí·ÏÀ¸·Î µé¾î°£´Ù. ±×·¯´Â µ¿¾È ´Ù¸¥ °ÍµéÀº ºí·ÏÈ­µÈ´Ù. ù ¹ø° ¾²·¹µå°¡ synchronized ºí·ÏÀ» Á¾·áÇÒ ¶§ ±â´Ù¸®°í ÀÖ´Â ¾²·¹µå°¡ µé¾î°¡¼­ ´Ù¸¥ Singleton °´Ã¼¸¦ ¸¸µç´Ù. µÎ ¹ø° ¾²·¹µå°¡ synchronized ºí·Ï¿¡ µé¾î°¥ ¶§, instanceÀÌ non-nullÀÎÁö¸¦ °Ë»çÇÏÁö ¾Ê´Â´Ù.

Double-checked locking
Listing 3ÀÇ ¹®Á¦¸¦ ÇØ°áÇÏ·Á¸é instance¸¦ °Ë»çÇؾßÇÑ´Ù. double-checked locking À̵ð¾öÀ» Listing 3¿¡ Àû¿ëÇϸé Listing 4ÀÇ °á°ú°¡ ³ª¿Â´Ù.

Listing 4. Double-checked locking ¿¹Á¦

public static Singleton getInstance()
{
  if (instance == null)
  {
    synchronized(Singleton.class) {  //1
      if (instance == null)          //2
        instance = new Singleton();  //3
    }
  }
  return instance;
}

double-checked locking ÀÌ·ÐÀº //2¿¡¼­ÀÇ µÎ¹ø° üũ°¡ µÎ °³ÀÇ ´Ù¸¥ Singleton °´Ã¼µéÀÌ Listing 3¿¡ ³ªÅ¸³­ °Íó·³ ¸¸µé¾îÁú ¼ö ¾øµµ·Ï ÇÑ´Ù´Â °ÍÀÌ´Ù:

  1. Thread 1Àº getInstance() ¸Þ¼Òµå·Î µé¾î°£´Ù.

  2. Thread 1Àº instance°¡ nullÀ̱⠶§¹®¿¡ //1¿¡ ÀÖ´Â synchronized ºí·ÏÀ¸·Î µé¾î°£´Ù.

  3. Thread 1Àº thread 2¿¡ ¼±Á¡µÈ´Ù.

  4. Thread 2´Â getInstance() ¸Þ¼Òµå·Î µé¾î°£´Ù.

  5. Thread 2´Â instance°¡ ¿©ÀüÈ÷ nullÀ̱⠶§¹®¿¡ //1¿¡¼­ lock ¾ò±â¸¦ ½ÃµµÇÑ´Ù. ÇÏÁö¸¸ thread 1ÀÌ lockÀ» º¸À¯ÇÏ°í Àֱ⠶§¹®¿¡ thread 2´Â //1¿¡¼­ ºí·ÏÇÑ´Ù.

  6. Thread 2´Â thread 1¿¡ ¼±Á¡µÈ´Ù.

  7. Thread 1Àº ½ÇÇàÇÏ°í ÀνºÅϽº°¡ //2¿¡¼­ ¿©ÀüÈ÷ null À̱⠶§¹®¿¡, Singleton °´Ã¼¸¦ ¸¸µé°í ÀÌ°ÍÀÇ ·¹ÆÛ·±½º¸¦ instance¿¡ ÇÒ´çÇÑ´Ù.

  8. Thread 1Àº synchronized ºí·ÏÀ» Á¾·áÇÏ°í getInstance() ¸Þ¼Òµå¿¡¼­ ÀνºÅϽº¸¦ ¸®ÅÏÇÑ´Ù.

  9. Thread 1Àº thread 2¿¡ ¼±Á¡µÈ´Ù.

  10. Thread 2´Â //1¿¡¼­ lockÀ» ¾ò¾î¼­ instance°¡ nullÀÎÁö¸¦ Á¡°ËÇÑ´Ù.

  11. instance°¡ non-nullÀ̱⠶§¹®¿¡, µÎ ¹ø° Singleton °´Ã¼´Â ¸¸µé¾îÁöÁö ¾Ê°í thread 1¿¡ ¸¸µé¾îÁø°ÍÀÌ ¸®ÅϵȴÙ.

double-checked locking ÀÌ·ÐÀº ¿Ïº®ÇÏ´Ù. ¾ÈŸ±õ°Ôµµ Çö½ÇÀº ±×¿Í ¹Ý´ë¶ó´Â °ÍÀÌ´Ù. double-checked locking°ú °ü·ÃÇÑ ¹®Á¦´Â ÀÌ°ÍÀÌ ´ÜÀÏ ¶Ç´Â ´ÙÁß ÇÁ·Î¼¼¼­ ¸Ó½Å¿¡¼­ ÀÛµ¿ÇÏ´Â °ÍÀ» º¸ÀåÇÒ ¼ö ¾ø´Ù´Â Á¡ÀÌ´Ù.

double-checked locking ½ÇÆд JVMÀÇ ¹ö±× ¶§¹®ÀÌ ¾Æ´Ï°í ÇöÀçÀÇ ÀÚ¹Ù Ç÷§Æû ¸Þ¸ð¸® ¸ðµ¨ ¶§¹®ÀÌ´Ù. ¸Þ¸ð¸® ¸ðµ¨Àº "³­ÀâÇÑ ÀÛ¼º"À» Çã¿ëÇÏ°í ÀÌ°ÍÀÌ À̵ð¾öÀÌ ½ÇÆÐÇÏ´Â ÁÖ¿ä ÀÌÀ¯ÀÌ´Ù.

out-of-order write
ÀÌ ¹®Á¦¸¦ ¼³¸íÇϱâ À§Çؼ­, Listing 4ÀÇ //3ÇàÀ» ´Ù½ÃÇѹø »ìÆ캸¾Æ¶ó. ÀÌ ÄÚµå´Â Singleton °´Ã¼¸¦ ¸¸µé°í °´Ã¼¸¦ ÂüÁ¶Çϱâ À§Çؼ­ instance º¯¼ö¸¦ ÃʱâÈ­ÇÑ´Ù. ÀÌ ÄÚµåÀÇ ¹®Á¦´Â instance º¯¼ö°¡ Singleton »ý¼ºÀÚÀÇ ¹Ùµð°¡ ½ÇÇàÇϱâ Àü¿¡ non-null ÀÌ µÉ ¼ö ÀÖ´Ù´Â Á¡ÀÌ´Ù.

ÀÌ°ÍÀº ¿©·¯ºÐÀÌ °¡´ÉÇÏ´Ù°í »ý°¢Çß´ø ¸ðµç°Í°ú ¹èÄ¡°¡ µÉ ¼ö ÀÖ´Ù. ÇÏÁö¸¸ °¡´ÉÇÑ Çö½ÇÀÌ´Ù.ÀÌ°ÍÀÌ ¾î¶»°Ô ¹ß»ýÇß´ÂÁö¸¦ ¼³¸íÇϱâÀü¿¡ ¾î¶»°Ô ÀÌ°ÍÀÌ double-checked locking À̵ð¾öÀ» °íÀå³Â´ÂÁö¸¦ »ìÆ캸¸é¼­ ÀÌ·¯ÇÑ Çö½ÇÀ» ¹Þ¾ÆµéÀÌÀÚ:

  1. Thread 1Àº getInstance() ¸Þ¼Òµå·Î µé¾î°£´Ù.

  2. Thread 1Àº //1ÀÇ synchronized ºí·ÏÀ¸·Î µé¾î°£´Ù. instance°¡ nullÀ̱⠶§¹®ÀÌ´Ù.

  3. Thread 1Àº //3 À¸·Î °¡¼­ non-null ÀνºÅϽº¸¦ ¸¸µç´Ù. »ý¼ºÀÚ°¡ ½ÇÇàÇϱâ ÀüÀÌ´Ù.

  4. Thread 1Àº thread 2¿¡ ¼±Á¡µÈ´Ù.

  5. Thread 2´Â ÀνºÅϽº°¡ nullÀÎÁö¸¦ Á¡°ËÇÑ´Ù. nullÀÌ ¾Æ´Ï±â ¶§¹®¿¡, thread 2´Â instance ·¹ÆÛ·±½º¸¦ ¿ÏÀüÈ÷ ¸¸µé¾îÁ³Áö¸¸ ºÎºÐÀûÀ¸·Î ÃʱâÈ­µÈ Singleton °´Ã¼·Î ¸®ÅÏÇÑ´Ù.

  6. Thread 2´Â thread 1¿¡ ¼±Á¡µÈ´Ù.

  7. Thread 1Àº »ý¼ºÀÚ¸¦ ½ÇÇàÇÔÀ¸·Î¼­ Singleton °´Ã¼ÀÇ ÃʱâÈ­¸¦ ¿Ï·áÇÏ°í ·¹ÆÛ·±½º¸¦ ¸®ÅÏÇÑ´Ù.

thread 2´Â ÇÑ °´Ã¼¸¦ ¸®ÅÏÇϴµ¥, ±× °´Ã¼ÀÇ »ý¼ºÀÚ´Â ½ÇÇàµÇÁö ¾Ê¾Ò´Ù.

À̸¦ ¼³¸íÇØÁÙ ´ÙÀ½ÀÇ °¡»ó Äڵ带 »ìÆ캸ÀÚ: instance =new Singleton();


mem = allocate();             //Allocate memory for Singleton object.
instance = mem;               //Note that instance is now non-null, but
                              //has not been initialized.
ctorSingleton(instance);      //Invoke constructor for Singleton passing
                              //instance.

Listing 5ÀÇ Äڵ带 º¸ÀÚ. getInstance() ¸Þ¼Òµå¸¦ °£·«ÇÏ°Ô ³ªÅ¸³Â´Ù. "double-checkedness"¸¦ Á¦°ÅÇß´Ù. instance=new Singleton(); ¶óÀÎÀ» JIT ÄÄÆÄÀÏ·¯°¡ ¾î¶»°Ô ÄÄÆÄÀÏÇÏ´ÂÁö¿¡¸¸ °ü½ÉÀÌ ÀÖ´Ù. ¾î¼Àºí¸® Äڵ忡¼­ »ý¼ºÀÚ°¡ ½ÇÇàµÈ´Ù´Â °ÍÀ» È®ÀÎÇϱâ À§ÇØ °£´ÜÇÑ »ý¼ºÀÚµµ Á¦°øÇß´Ù.

Listing 5. out-of-order write¸¦ Ç¥ÇöÇÑ Singleton Ŭ·¡½º

class Singleton
{
  private static Singleton instance;
  private boolean inUse;
  private int val;  

  private Singleton()
  {
    inUse = true;
    val = 5;
  }
  public static Singleton getInstance()
  {
    if (instance == null)
      instance = new Singleton();
    return instance;
  }
}

Listing 6¿¡´Â getInstance() ¸Þ¼ÒµåÀÇ ¹Ùµð¸¦ À§ÇÑ Sun JDK 1.2.1 JIT ÄÄÆÄÀÏ·¯¿¡¼­ ¸¸µé¾îÁø ¾î¼Àºí¸® Äڵ尡 Æ÷ÇԵǾî ÀÖ´Ù.

Listing 6. Listing 5 Äڵ忡¼­ ¸¸µé¾îÁø ¾î¼Àºí¸® ÄÚµå

;asm code generated for getInstance
054D20B0   mov         eax,[049388C8]      ;load instance ref
054D20B5   test        eax,eax             ;test for null
054D20B7   jne         054D20D7
054D20B9   mov         eax,14C0988h
054D20BE   call        503EF8F0            ;allocate memory
054D20C3   mov         [049388C8],eax      ;store pointer in 
                                           ;instance ref. instance  
                                           ;non-null and ctor
                                           ;has not run
054D20C8   mov         ecx,dword ptr [eax] 
054D20CA   mov         dword ptr [ecx],1   ;inline ctor - inUse=true;
054D20D0   mov         dword ptr [ecx+4],5 ;inline ctor - val=5;
054D20D7   mov         ebx,dword ptr ds:[49388C8h]
054D20DD   jmp         054D20B0

ÀÌ ¾î¼Àºí¸® ÄÚµå´Â getInstance() ¸Þ¼Òµå¸¦ È£ÃâÇÏ´Â Å×½ºÆ® ÇÁ·Î±×·¥À» ½ÇÇàÇÏ¿© ¸¸µé¾îÁ³´Ù. ÇÁ·Î±×·¥ÀÌ ½ÇÇàµÇ´Â µ¿¾È Microsoft Visual C++ µð¹ö°Å¸¦ ½ÇÇàÇÏ°í ÀÌ°ÍÀ» ÀÚ¹Ù ÇÁ·Î¼¼½º¿¡ ºÙ¿´´Ù.

¾î¼Àºí¸® ÄÚµåÀÇ Ã³À½ µÎ °³ÀÇ ÇàÀº 049388C8 ¸Þ¸ð¸® ·ÎÄÉÀ̼ǿ¡¼­ instance ·¹ÆÛ·±½º¸¦ eax ·Î ·ÎµùÇÏ°í nullÀ» Å×½ºÆ® ÇÑ´Ù. ÀÌ°ÍÀº Listing 5ÀÇ Ã¹ ÇàÀÇ getInstance()¸Þ¼Òµå¿Í »óÀÀÇÑ´Ù. ÀÌ ¸Þ¼Òµå°¡ óÀ½ È£ÃâµÇ°í instance´Â nullÀ̸é ÄÚµå´Â B9À¸·Î ÁøÇàµÈ´Ù. BE¿¡ ÀÖ´Â ÄÚµå´Â Singleton °´Ã¼¿ë Èü¿¡¼­ ¸Þ¸ð¸®¸¦ ÇÒ´çÇÏ¿© eaxÀÇ ¸Þ¸ð¸®¿¡ Æ÷ÀÎÅ͸¦ ÀúÀåÇÑ´Ù. C3´Â eax ¿¡¼­ Æ÷ÀÎÅ͸¦ °¡Á®´Ù°¡ 049388C8 ¸Þ¸ð¸® ·ÎÄÉÀ̼ǿ¡ ÀνºÅϽº ·¹ÆÛ·±½º¿¡ ÀúÀåÇÑ´Ù. °á°úÀûÀ¸·Î ÀνºÅϽº´Â ÇöÀç non-nullÀÌ°í À¯È¿ÇÑ Singleton °´Ã¼¸¦ ÂüÁ¶ÇÑ´Ù. ÇÏÁö¸¸ ÀÌ °´Ã¼¿ë »ý¼ºÀÚ´Â ¾ÆÁ÷ ½ÇÇàµÇÁö ¾Ê¾Ò°í ±×°ÍÀº double-checked lockingÀÌ ¹®Á¦°¡ ÀÖ´Ù´Â °ÍÀÌ´Ù. C8 ¶óÀο¡¼­,instance Æ÷ÀÎÅÍ´Â ¿ªÂüÁ¶µÇ°í ecx¿¡ ÀúÀåµÈ´Ù. CA¿Í D0 ÇàÀº true¿Í 5 °ªÀ» Singleton °´Ã¼¿¡ ÀúÀåÇÏ´Â ÀζóÀÎ »ý¼ºÀÚ¸¦ ³ªÅ¸³½´Ù. C3 ÇàÀ» ½ÇÇàÇÏ°í ³ª¼­ ´Ù¸¥ ¾²·¹µå¿¡ ÀÇÇØ ÀÌ Äڵ尡 ÀÎÅÍ·´Æ®µÈ´Ù¸é »ý¼ºÀÚ¸¦ ¿Ï·áÇϱâ Àü¿¡ double-checked lockingÀº ½ÇÆÐÇÑ´Ù.

¸ðµç JIT ÄÄÆÄÀÏ·¯°¡ À§¿Í °°Àº Äڵ带 »ý¼ºÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. ¾î¶²°ÍÀº »ý¼ºÀÚ°¡ ½ÇÇàµÈ ÈÄ ¹Ù·Î ÀνºÅϽº°¡ non-nullÀÌ µÇ´Â Äڵ带 ¸¸µç´Ù. IBM SDK for Java technology, version 1.3°ú Sun JDK 1.3 ¸ðµÎ ÀÌ¿Í °°Àº Äڵ带 ¸¸µç´Ù. ÇÏÁö¸¸ ÀÌ·¯ÇÑ ÀνºÅϽº¿¡ double-checked lockingÀ» »ç¿ëÇØ¾ß µÈ´Ù´Â °ÍÀ» ¸»ÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. ÀÌ°ÍÀÌ ½ÇÆÐÇÒ ¼ö ÀÖ´Â ´Ù¸¥ ÀÌÀ¯µéÀÌ ÀÖ´Ù. °Ô´Ù°¡ ¾î¶² JVM¿¡¼­ ¿©·¯ºÐÀÇ Äڵ尡 ½ÇÇàµÉÁö¸¦ Ç×»ó ¾Ë°íÀִ°ÍÀº ¾Æ´ÏÁö ¾Ê´Â°¡? ±×¸®°í JIT ÄÄÆÄÀÏ·¯´Â ÀÌ À̵ð¾öÀ» ÁߴܽÃÅ°´Â Äڵ带 ¸¸µé±âÀ§ÇØ ¾ðÁ¦³ª º¯È­ÇÒ ¼ö ÀÖ´Ù.

Double-checked locking: Take two
ÇöÀç double-checked locking Äڵ尡 ½ÇÇàµÇÁö ¾Ê´Â´Ù¸é ´Ù¸¥ ÄÚµå ¹öÀüÀ» Á¦¾ÈÇÏ°Ú´Ù (Listing 7). out-of-order write ¹®Á¦¸¦ ¹æÁöÇϱâ À§ÇÔÀÌ´Ù.

Listing 7. out-of-order write ¹®Á¦ ÇØ°á

public static Singleton getInstance()
{
  if (instance == null)
  {
    synchronized(Singleton.class) {      //1
      Singleton inst = instance;         //2
      if (inst == null)
      {
        synchronized(Singleton.class) {  //3
          inst = new Singleton();        //4
        }
        instance = inst;                 //5
      }
    }
  }
  return instance;
}

Listing 7ÀÇ Äڵ带 º¸°ÔµÇ¸é »óȲÀÌ ¿ì½À°Ô µÇ°íÀÖ´Ù´Â °ÍÀ» ¾Ë°ÔµÈ´Ù. ±â¾ïÇؾßÇÒ °ÍÀº double-checked lockingÀº °£´ÜÇÑ ¼¼ ¶óÀÎÀÇ getInstance() ¸Þ¼ÒµåÀÇ µ¿±âÈ­¸¦ ¸·À» ¼ö´ÜÀ¸·Î ¸¸µé¾îÁ³´Ù´Â °ÍÀÌ´Ù. Listing 7ÀÇ ÄÚµå´Â ¼Õ¿¡¼­ ¶°³µ´Ù. ÀÌ ÄÚµå´Â ¹®Á¦¸¦ ÇØ°áÇÏÁö ¾Ê´Â´Ù. õõÈ÷ ±× ÀÌÀ¯¸¦ »ìÆ캸ÀÚ.

out-of-order write ¹®Á¦¸¦ ¹æÁöÇϱâ À§ÇØ ½ÃµµµÇ¾ú´Ù. À̸¦ inst ·ÎÄà º¯¼ö¿Í µÎ ¹ø° synchronized ºí·ÏÀ» ÀÌ¿ëÇÏ¿© ¼öÇàÇÑ´Ù:

  1. Thread 1 getInstance() ¸Þ¼Òµå·Î µé¾î°£´Ù.

  2. instance°¡ nullÀ̱⶧¹®¿¡, thread 1Àº //1¿¡¼­ ù ¹ø° synchronized ºí·ÏÀ¸·Î µé¾î°£´Ù.

  3. ·ÎÄà º¯¼öinst´Â instance °ªÀ» °¡Áö°í ÀÌ°ÍÀº //2 ¿¡¼­ nullÀÌ´Ù.

  4. inst°¡ null À̱⠶§¹®¿¡, thread 1Àº //3ÀÇ µÎ ¹ø° synchronized ºí·ÏÀ¸·Î µé¾î°£´Ù.

  5. Thread 1Àº //4¿¡¼­ ÄÚµå ½ÇÇàÀ» ½ÃÀÛÇϸ鼭 Singleton »ý¼ºÀÚ°¡ ½ÇÇàµÇ±â Àü¿¡ inst¸¦ non-null·Î ¸¸µç´Ù. (ÀÌ°ÍÀÌ out-of-order write ¹®Á¦ÀÌ´Ù.)

  6. Thread 1Àº Thread 2¿¡ ¼±Á¡µÈ´Ù.

  7. Thread 2´Â getInstance() ¸Þ¼Òµå·Î µé¾î°£´Ù.

  8. instance°¡ nullÀ̱⠶§¹®¿¡, thread 2´Â //1¿¡ Àִ ù ¹ø° synchronized ºí·ÏÀ¸·Î µé¾î°¡´Â °ÍÀ» ½ÃµµÇÑ´Ù. thread 1ÀÌ ÇöÀç ÀÌ lockÀ» º¸À¯ÇÏ°í Àֱ⠶§¹®¿¡, thread 2´Â ºí·ÏµÈ´Ù.

  9. Thread 1Àº //4ÀÇ ½ÇÇàÀ» ¿Ï·áÇÑ´Ù.

  10. Thread 1Àº ¿ÏÀüÈ÷ »ý¼ºµÈ Singleton °´Ã¼¸¦ //5ÀÇ instance º¯¼ö¿¡ ÇÒ´çÇÏ°í synchronized ºí·Ï ¸ðµÎ¸¦ Á¾·áÇÑ´Ù.

  11. Thread 1Àº instance¸¦ ¸®ÅÏÇÑ´Ù.

  12. Thread 2´Â ½ÇÇàÇؼ­ instance¸¦ //2ÀÇ inst¿¡ ÇÒ´çÇÑ´Ù.

  13. Thread 2´Â instance°¡ non-nullÀ̶ó´Â °ÍÀ» È®ÀÎÇÏ°í À̸¦ ¸®ÅÏÇÑ´Ù.

ÇÙ½É ¶óÀÎÀº //5 ÀÌ´Ù. ÀÌ ¶óÀÎÀº instance°¡ null À̰ųª ¿ÏÀüÈ÷ »ý¼ºµÈ Singleton °´Ã¼¸¦ ÂüÁ¶ÇÑ´Ù´Â °ÍÀ» È®ÀÎÇϵµ·Ï µÇ¾îÀÖ´Ù. ¹®Á¦´Â À̷аú Áø½ÇÀÌ Á÷±³ÇÏ¸ç ½ÇÇàµÇ´Â °÷¿¡¼­ ¹ß»ýÇÑ´Ù.

Listing 7ÀÇ ÄÚµå´Â ¸Þ¸ð¸® ¸ðµ¨ÀÇ ÇöÀç Á¤ÀÇ ¶§¹®¿¡ ÀÛµ¿ÇÏÁö ¾Ê´Â´Ù. Java Language Specification (JLS)Àº synchronized ºí·Ï ¾È¿¡¼­ ÀÛ¼ºµÈ Äڵ尡 synchronized ºí·Ï ¹ÛÀ¸·Î À̵¿ÇÏÁö ¸øÇϵµ·Ï µÇ¾îÀÖ´Ù. ÇÏÁö¸¸, synchronized ºí·Ï¿¡ ¾ø´Â Äڵ尡 Äڵ尡 synchronized ºí·Ï ¾ÈÀ¸·Î À̵¿ÇÒ ¼ö ¾ø´Ù´Â °ÍÀ» ¶æÇÏ´Â °ÍÀº ¾Æ´Ï´Ù.

JIT ÄÄÆÄÀÏ·¯´Â ¿©±â¿¡¼­ ÃÖÀûÈ­ ±âȸ¸¦ º»´Ù. ÃÖÀûÈ­´Â //4¿¡ ÀÖ´Â ÄÚµå¿Í //5 ¿¡ ÀÖ´Â Äڵ带 Á¦°ÅÇÏ¿© À̸¦ Á¶ÇÕÇÏ¿© Listing 8°ú °°Àº Äڵ带 ¸¸µç´Ù:

Listing 8. Listing 7ÀÇ ÃÖÀûÈ­ ÄÚµå

public static Singleton getInstance()
{
  if (instance == null)
  {
    synchronized(Singleton.class) {      //1
      Singleton inst = instance;         //2
      if (inst == null)
      {
        synchronized(Singleton.class) {  //3
          //inst = new Singleton();      //4
          instance = new Singleton();               
        }
        //instance = inst;               //5
      }
    }
  }
  return instance;
}

ÃÖÀûÈ­°¡ µÇ¸é ÀÌÀü°ú °°Àº out-of-order write ¹®Á¦°¡ »ý±ä´Ù.

volatile
inst º¯¼ö¿Í instance º¯¼ö¿¡ volatile Å°¿öµå¸¦ »ç¿ëÇÏ´Â °æ¿ìµµ ÀÖ´Ù. JLS (Âü°íÀÚ·á)¿¡¼­ volatileÀÌ ¼±¾ðµÈ º¯¼ö´Â ¿µ¼Ó¼ºÀÌ ÀÖ¾î ÀçÁ¤¸® µÇÁö ¾Ê¾Æ¾ß ÇÑ´Ù. double-checked locking °ú °ü·ÃÇÑ ¹®Á¦¸¦ ÇØ°áÇϱâ À§ÇØ volatileÀ» »ç¿ëÇÒ ¶§ µÎ °¡Áö ¹®Á¦°¡ ¹ß»ýÇÑ´Ù:

  • ¿©±â¼­ÀÇ ¹®Á¦´Â ¼øÂ÷Àû ¿µ¼Ó¼º¿¡ ÀÖÁö ¾Ê´Ù. ÄÚµå´Â À̵¿µÇ°í ÀçÁ¤¸® µÇÁö ¾Ê´Â´Ù.

  • ¸¹Àº JVMÀÌ ¼øÂ÷Àû ¿µ¼Ó¼ºÀ» Á¤È®È÷ °í·ÁÇÑ volatile À» ±¸ÇöÇÏÁö ¾Ê´Â´Ù.
Listing 9. volatileÀÇ ¼øÂ÷Àû ¿µ¼Ó¼º

class test
{
  private volatile boolean stop = false;
  private volatile int num = 0;

  public void foo()
  {
    num = 100;    //This can happen second
    stop = true;  //This can happen first
    //...
  }

  public void bar()
  {
    if (stop)
      num += num;  //num can == 0!
  }
  //...
}

JLS¿¡ ÀÇÇϸé, stop°ú numÀÌ volatile·Î ¼±¾ðµÇ±â ¶§¹®¿¡, ±×µéÀº ¼øÂ÷ÀûÀ¸·Î ¿µ¼ÓÀûÀÌ¿©¾ß ÇÑ´Ù. ÀÌ´Â, stopÀÌ ¾ðÁ¦³ª trueÀ̸é, numÀº 100À¸·Î ¼³Á¤µÇ¾î¾ß ÇÑ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù. ÇÏÁö¸¸, ¸¹Àº JVMÀÌ volatileÀÇ ¼øÂ÷Àû ¿µ¼Ó¼º ±â´ÉÀ» ±¸ÇöÇÏÁö ¾Ê±â ¶§¹®¿¡ ÀÌ·¯ÇÑ °Í¿¡ ÀÇÁ¸ÇÒ ¼ö ¾ø´Ù. µû¶ó¼­ thread 1ÀÌ foo¸¦ È£ÃâÇÏ°í thread 2°¡ bar¸¦ µ¿½Ã¿¡ È£ÃâÇϸé, thread 1Àº num ÀÌ 100À¸·Î ¼³Á¤µÇ±â Àü¿¡ stopÀ» true·Î ¼³Á¤ÇؾßÇÑ´Ù. ÀÌ·¸°Ô µÇ¸é thread 2¿¡¼­ stopÀÌ true·Î ¼³Á¤µÇ°í numÀº ¿©ÀüÈ÷ 0À¸·Î ¼³Á¤µÈ´Ù.

¼Ö·ç¼Ç
¸ðµç JVM ±¸Çö¿¡¼­ ÀÛµ¿ÇÑ´Ù´Â °ÍÀ» º¸ÀåÇÒ ¼ö ¾ø±â ¶§¹®¿¡ ¾î¶² ÇüÅ·εç double-checked lockingÀº »ç¿ëµÇ¾î¼­´Â ¾ÈµÈ´Ù. JSR-133Àº ¸Þ¸ð¸® ¸ðµ¨ °ü·ÃÇÑ ¹®Á¦¸¦ ¾ð±ÞÇÏ°í ÀÖÁö¸¸ double-checked lockingÀº »õ·Î¿î ¸Þ¸ð¸® ¸ðµ¨¿¡¼­ Áö¿øµÇÁö ¾Ê´Â´Ù. µû¶ó¼­ ´ÙÀ½ µÎ °¡Áö ¿É¼ÇÀÌ ÀÖ´Ù:

  • getInstance() ¸Þ¼ÒµåÀÇ µ¿±âÈ­¸¦ ¼ö¶ôÇÑ´Ù. (Listing 2).

  • µ¿±âÈ­¸¦ ±×¸¸µÎ°í static Çʵ带 »ç¿ëÇÑ´Ù.

Option 2´Â Listing 10¿¡ ³ª¿ÍÀÖ´Ù:

Listing 10. static Çʵ带 ÀÌ¿ëÇÑ Singleton ±¸Çö

class Singleton
{
  private Vector v;
  private boolean inUse;
  private static Singleton instance = new Singleton();

  private Singleton()
  {
    v = new Vector();
    inUse = true;
    //...
  }

  public static Singleton getInstance()
  {
    return instance;
  }
}

Listing 10ÀÇ ÄÚµå´Â µ¿±âÈ­¸¦ »ç¿ëÇÏÁö ¾Ê°í static getInstance() ¸Þ¼Òµå¿¡ È£ÃâÀÌ ÀÖÀ»¶§±îÁö Singleton °´Ã¼°¡ ¸¸µé¾îÁöÁö ¾Ê´Â´Ù´Â °ÍÀ» È®½ÇÈ÷ ÇÏ°íÀÖ´Ù.

½ºÆ®¸µÀº º¯ÇÏÁö ¾Ê´Â´Ù!
out-of-order writes ¹®Á¦°¡ ÀÖ´Â String Ŭ·¡½º¿Í »ý¼ºÀÚ ½ÇÇà¿¡ ¾Õ¼­ non-null ÀÌ µÇ´Â ·¹ÆÛ·±½º°¡ ÀÌ»óÇÒ °ÍÀÌ´Ù. ´ÙÀ½ Äڵ带 º¸ÀÚ:


private String str;
//...
str = new String("hello");

String Ŭ·¡½º´Â º¯ÇÏÁö ¾Ê´Â´Ù. ÇÏÁö¸¸ out-of-order write ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö Àִ°¡? ¹®Á¦´Â ±×·² ¼ö ÀÖ´Ù´Â °ÍÀÌ´Ù. String str·Î ¾×¼¼½º ÇÏ´Â µÎ °³ÀÇ ¾²·¹µå¸¦ »ý°¢Çغ¸ÀÚ. ÇÑ ¾²·¹µå´Â str ·¹ÆÛ·±½º°¡ »ý¼ºÀÚ°¡ ½ÇÇàÇÏÁö ¾Ê´Â °÷¿¡¼­ String °´Ã¼¸¦ ÂüÁ¶ÇÑ´Ù´Â °ÍÀ» º»´Ù. »ç½Ç Listing 11¿¡´Â ÀÌ·¯ÇÑ °ÍÀÌ ¹ß»ýÇÏ´Â °ÍÀ» º¸¿©ÁØ´Ù. ÀÌ ÄÚµå´Â ³»°¡ Å×½ºÆ® ÇÑ JVM ·Î¸¸ °íÀåÀ» ÀÏÀ¸Å²´Ù´Â °ÍÀ» ¸í½ÉÇضó. IBM 1.3°ú Sun 1.3 JVMÀº º¯ÇÏÁö ¾Ê´Â StringÀ» ¸¸µç´Ù

Listing 11. Mutable String ¿¹Á¦

class StringCreator extends Thread
{
  MutableString ms;
  public StringCreator(MutableString muts)
  {
    ms = muts;
  }
  public void run()
  {
    while(true)
      ms.str = new String("hello");          //1
  }
}
class StringReader extends Thread
{
  MutableString ms;
  public StringReader(MutableString muts)
  {
    ms = muts;
  }
  public void run()
  {
    while(true)
    {
      if (!(ms.str.equals("hello")))         //2
      {
        System.out.println("String is not immutable!");
        break;
      }
    }
  }
}
class MutableString
{
  public String str;                         //3
  public static void main(String args[])
  {
    MutableString ms = new MutableString();  //4
    new StringCreator(ms).start();           //5
    new StringReader(ms).start();            //6
  }
}

ÀÌ ÄÚµå´Â //3ÀÇ µÎ °³ÀÇ ¾²·¹µå¿¡ ÀÇÇØ °øÀ¯µÈ String ·¹ÆÛ·±½º¸¦ Æ÷ÇÔÇÏ´Â //4ÀÇ MutableString Ŭ·¡½º¸¦ ¸¸µç´Ù. //5¿Í //6¶óÀο¡ µÎ °³ÀÇ °³º° ¾²·¹µå¿¡ StringCreator¿Í StringReader¶ó´Â µÎ °³ÀÇ °´Ã¼°¡ ¸¸µé¾îÁö¸é¼­ MutableString °´Ã¼¿¡ ·¹ÆÛ·±½º¸¦ Àü´ÞÇÑ´Ù. StringCreator Ŭ·¡½º´Â ¹«ÇÑ ·çÇÁ·Î µé¾î°¡°í //1¿¡¼­ "hello" °ªÀ» °¡Áø String °´Ã¼¸¦ ¸¸µç´Ù. StringReader´Â ¹«ÇÑ ·çÇÁ·Î µé¾î°¡°í ÇöÀç String °´Ã¼°¡ //2¿¡¼­ "hello" °ªÀ» °®°í ÀÖ´ÂÁö¸¦ È®ÀÎÇÑ´Ù. ±×·¸Áö ¾Ê´Ù¸é, StringReader ¾²·¹µå´Â ¸Þ½ÃÁö¸¦ ÇÁ¸°ÆÃÇÏ°í Á¤ÁöÇÑ´Ù. String Ŭ·¡½º´Â º¯ÇÏÁö ¾Ê°í ÀÌ ÇÁ·Î±×·¥¿¡¼­ ¾î¶² ¾Æ¿ôDzµµ º¼ ¼ö ¾ø´Ù.

Sun JDK 1.2.1°°Àº ¿À·¡µÈ JVM ¿¡¼­ ÀÌ Äڵ带 ½ÇÇàÇϸé out-of-order write ÇÁ·Î±×·¥ÀÌ µÇ°í non-immutable StringÀÌ µÈ´Ù.

¿ä¾à
singletonÀÇ ºñ½Ñ µ¿±âÈ­¸¦ ÇÇÇϱâÀ§ÇØ Æ¯º°È÷ õÀçÀûÀÎ ÇÁ·Î±×·¡¸ÓµéÀº double-checked locking À̵ð¾öÀ» °³¹ßÇß´Ù. ¾àÇÑ ¸Þ¸ð¸® ¸ðµ¨ÀÇ ºÐ¾ß¸¦ ÀçÁ¤ÀÇÇÏ´Â ÀÛ¾÷ÀÌ ÁøÇàÁßÀÌ´Ù. ÇÏÁö¸¸ ¾Æ¹«¸® »õ·Î¿î ¸Þ¸ð¸® ¸ðµ¨À̾ double-checked lockingÀº ÀÛµ¿ÇÏÁö ¾ÊÀ» °ÍÀÌ´Ù. ÀÌ ¹®Á¦¿¡ ´ëÇÑ ÃÖ»óÀÇ ¼Ö·ç¼ÇÀº µ¿±âÈ­¸¦ ¼ö¶ôÇϰųª static field¸¦ »ç¿ëÇÏ´Â °ÍÀÌ´Ù.

Âü°íÀÚ·á

ÇÊÀÚ¼Ò°³
Peter HaggarPeter Haggar´Â IBMÀÇ ¼ÒÇÁÆ®¿þ¾î ¿£Áö´Ï¾îÀÌ´Ù. Practical Java Programming Language Guide (Addison-Wesley)ÀÇ ÀúÀÚÀ̸ç ÀÚ¹Ù ÇÁ·Î±×·¡¹Ö °ü·ÃÇÏ¿© ¸¹Àº ±ÛÀ» ÁýÇÊÇß´Ù. °³¹ß Åø, Ŭ·¡½º ¶óÀ̺귯¸®, OS µî ±¤¹üÀ§ÇÑ ºÐ¾ß¿¡ ¸¹Àº °æÇèÀ» °®°í ÀÖ´Ù.



ÀÌ ±â»ç¿¡ ´ëÇÏ¿© ¾î¶»°Ô »ý°¢ÇϽʴϱî?

Á¤¸» ÁÁ´Ù (5) ÁÁ´Ù (4) ±×Àú±×·¸´Ù (3) ¼öÁ¤º¸¿ÏÀÌ ÇÊ¿äÇÏ´Ù(2) ÇüÆí¾ø´Ù (1)

  È¸»ç¼Ò°³  |  °³ÀÎÁ¤º¸ º¸È£Á¤Ã¥  |  ¹ý·ü  |  ¹®ÀÇ