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()
¸Þ¼Òµå¸¦ µ¿½Ã¿¡ È£ÃâÇÏ°í ´ÙÀ½ À̺¥Æ®¸¦ µû¶ó°¡´Â µÎ °³ÀÇ ¾²·¹µå¸¦ »ý°¢Çغ¸ÀÚ:
Thread 1˼ getInstance()
¸Þ¼Òµå¸¦ È£ÃâÇÏ°í //1¿¡¼ ±×
instance
°¡ null
À̶ó´Â °ÍÀ» °áÁ¤ÇÑ´Ù.
Thread 1˼ if
ºí·ÏÀ¸·Î µé¾î°¡Áö¸¸, //2ÀÇ ¶óÀÎÀ» ½ÇÇàÇϱâ Àü¿¡ thread 2¿¡
¼±Á¡µÈ´Ù.
Thread 2´Â getInstance()
¸Þ¼Òµå¸¦ È£ÃâÇÏ°í ±×
instance
°¡ //1¿¡¼ null
À̶ó´Â °ÍÀ» °áÁ¤ÇÑ´Ù.
Thread 2´Â if
ºí·ÏÀ¸·Î µé¾î°¡¼ »õ·Î¿î Singleton
°´Ã¼¸¦
¸¸µé°í instance
º¯¼ö¸¦ ÀÌ »õ·Î¿î //2¿¡ ÀÖ´Â »õ·Î¿î °´Ã¼¿¡ ÇÒ´çÇÑ´Ù.
Thread 2´Â //3¿¡ ÀÖ´Â Singleton
°´Ã¼ ·¹ÆÛ·±½º¸¦ ¸®ÅÏÇÑ´Ù.
Thread 2´Â thread 1¿¡ ¼±Á¡µÈ´Ù.
Thread 1´Â ³²°ÜÁø °÷¿¡¼ ºÎÅÍ ½ÃÀÛÇÏ°í ´Ù¸¥ Singleton
°´Ã¼°¡ ¸¸µé¾îÁö´Â °á°ú°¡ µÈ
//2 ¶óÀÎÀ» ½ÇÇàÇÑ´Ù.
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¿¡ ³ªÅ¸³ °Íó·³ ¸¸µé¾îÁú ¼ö ¾øµµ·Ï ÇÑ´Ù´Â °ÍÀÌ´Ù:
Thread 1˼ getInstance()
¸Þ¼Òµå·Î µé¾î°£´Ù.
Thread 1˼ instance
°¡ null
À̱⠶§¹®¿¡ //1¿¡ ÀÖ´Â
synchronized
ºí·ÏÀ¸·Î µé¾î°£´Ù.
Thread 1Àº thread 2¿¡ ¼±Á¡µÈ´Ù.
Thread 2´Â getInstance()
¸Þ¼Òµå·Î µé¾î°£´Ù.
Thread 2´Â instance
°¡ ¿©ÀüÈ÷ null
À̱⠶§¹®¿¡ //1¿¡¼
lock ¾ò±â¸¦ ½ÃµµÇÑ´Ù. ÇÏÁö¸¸ thread 1ÀÌ lockÀ» º¸À¯ÇÏ°í Àֱ⠶§¹®¿¡ thread 2´Â //1¿¡¼
ºí·ÏÇÑ´Ù.
Thread 2´Â thread 1¿¡ ¼±Á¡µÈ´Ù.
Thread 1Àº ½ÇÇàÇÏ°í ÀνºÅϽº°¡ //2¿¡¼ ¿©ÀüÈ÷ null
À̱⠶§¹®¿¡,
Singleton
°´Ã¼¸¦ ¸¸µé°í ÀÌ°ÍÀÇ ·¹ÆÛ·±½º¸¦ instance
¿¡ ÇÒ´çÇÑ´Ù.
Thread 1˼ synchronized
ºí·ÏÀ» Á¾·áÇÏ°í
getInstance()
¸Þ¼Òµå¿¡¼ ÀνºÅϽº¸¦ ¸®ÅÏÇÑ´Ù.
Thread 1Àº thread 2¿¡ ¼±Á¡µÈ´Ù.
Thread 2´Â //1¿¡¼ lockÀ» ¾ò¾î¼ instance
°¡
null
ÀÎÁö¸¦ Á¡°ËÇÑ´Ù.
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 À̵ð¾öÀ» °íÀå³Â´ÂÁö¸¦ »ìÆ캸¸é¼ ÀÌ·¯ÇÑ Çö½ÇÀ» ¹Þ¾ÆµéÀÌÀÚ:
Thread 1˼ getInstance()
¸Þ¼Òµå·Î µé¾î°£´Ù.
Thread 1˼ //1˂ synchronized
ºí·ÏÀ¸·Î µé¾î°£´Ù.
instance
°¡ null
À̱⠶§¹®ÀÌ´Ù.
Thread 1Àº //3 À¸·Î °¡¼ non-null
ÀνºÅϽº¸¦ ¸¸µç´Ù. »ý¼ºÀÚ°¡ ½ÇÇàÇϱâ ÀüÀÌ´Ù.
Thread 1Àº thread 2¿¡ ¼±Á¡µÈ´Ù.
Thread 2´Â ÀνºÅϽº°¡ null
ÀÎÁö¸¦ Á¡°ËÇÑ´Ù. nullÀÌ ¾Æ´Ï±â ¶§¹®¿¡, thread 2´Â
instance
·¹ÆÛ·±½º¸¦ ¿ÏÀüÈ÷ ¸¸µé¾îÁ³Áö¸¸ ºÎºÐÀûÀ¸·Î ÃʱâÈµÈ Singleton
°´Ã¼·Î ¸®ÅÏÇÑ´Ù.
Thread 2´Â thread 1¿¡ ¼±Á¡µÈ´Ù.
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
ºí·ÏÀ» ÀÌ¿ëÇÏ¿© ¼öÇàÇÑ´Ù:
Thread 1 getInstance()
¸Þ¼Òµå·Î µé¾î°£´Ù.
instance
°¡ null
À̱⶧¹®¿¡, thread 1Àº //1¿¡¼ ù ¹ø°
synchronized
ºí·ÏÀ¸·Î µé¾î°£´Ù.
·ÎÄà º¯¼öinst
´Â instance
°ªÀ» °¡Áö°í ÀÌ°ÍÀº //2 ¿¡¼
null
ÀÌ´Ù.
inst
°¡ null
À̱⠶§¹®¿¡, thread 1Àº //3ÀÇ µÎ ¹ø°
synchronized
ºí·ÏÀ¸·Î µé¾î°£´Ù.
Thread 1Àº //4¿¡¼ ÄÚµå ½ÇÇàÀ» ½ÃÀÛÇÏ¸é¼ Singleton
»ý¼ºÀÚ°¡ ½ÇÇàµÇ±â Àü¿¡
inst
¸¦ non-null
·Î ¸¸µç´Ù. (ÀÌ°ÍÀÌ out-of-order write
¹®Á¦ÀÌ´Ù.)
Thread 1Àº Thread 2¿¡ ¼±Á¡µÈ´Ù.
Thread 2´Â getInstance()
¸Þ¼Òµå·Î µé¾î°£´Ù.
instance
°¡ null
À̱⠶§¹®¿¡, thread 2´Â //1¿¡ Àִ ù
¹ø° synchronized
ºí·ÏÀ¸·Î µé¾î°¡´Â °ÍÀ» ½ÃµµÇÑ´Ù. thread 1ÀÌ ÇöÀç ÀÌ lockÀ»
º¸À¯ÇÏ°í Àֱ⠶§¹®¿¡, thread 2´Â ºí·ÏµÈ´Ù.
Thread 1Àº //4ÀÇ ½ÇÇàÀ» ¿Ï·áÇÑ´Ù.
Thread 1Àº ¿ÏÀüÈ÷ »ý¼ºµÈ Singleton
°´Ã¼¸¦ //5ÀÇ
instance
º¯¼ö¿¡ ÇÒ´çÇÏ°í synchronized
ºí·Ï ¸ðµÎ¸¦
Á¾·áÇÑ´Ù.
Thread 1˼ instance
¸¦ ¸®ÅÏÇÑ´Ù.
Thread 2´Â ½ÇÇàÇؼ instance
¸¦ //2ÀÇ inst
¿¡ ÇÒ´çÇÑ´Ù.
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
¸¦ »ç¿ëÇÏ´Â °ÍÀÌ´Ù.
Âü°íÀÚ·á
Practical
Java Programming Language Guide (Addison-Wesley, 2000), Peter
Haggar.
The
Java Language Specification, Second Edition : Bill Joy, et. al.
(Addison-Wesley, 2000).
The
Java Virtual Machine Specification, Second Edition :Tim Lindholm
and Frank Yellin (Addison-Wesley, 1999).
Bill Pugh˂ Java Memory Model ˴
»çÀÌÆ® ¹æ¹®.
Dr. Dobb's Journal
.
JSR-133 .
"Threading
lightly: Synchronization is not the enemy " (developerWorks ,
2001³â 7¿ù).
"Threading
lightly: Sometimes it's best not to share " (developerWorks ,
2001³â 10¿ù), Brian Goetz.
"Writing
multithreaded Java applications " (developerWorks , 2001³â 2¿ù),
Alex Roetter.
"If
I were king: A proposal for fixing the Java programming language's
threading problems " (developerWorks , 2000³â 10¿ù).
developerWorks Java
technology zone .