ÓÑÇéÌáʾ£ºÈç¹û±¾ÍøÒ³´ò¿ªÌ«Âý»òÏÔʾ²»ÍêÕû£¬Çë³¢ÊÔÊó±êÓÒ¼ü¡°Ë¢Ð¡±±¾ÍøÒ³£¡
VB2008´ÓÈëÃŵ½¾«Í¨(PDF¸ñʽӢÎÄ°æ)-µÚ92²¿·Ö
¿ì½Ý²Ù×÷: °´¼üÅÌÉÏ·½Ïò¼ü ¡û »ò ¡ú ¿É¿ìËÙÉÏÏ·ҳ °´¼üÅÌÉ쵀 Enter ¼ü¿É»Øµ½±¾ÊéĿ¼ҳ °´¼üÅÌÉÏ·½Ïò¼ü ¡ü ¿É»Øµ½±¾Ò³¶¥²¿! Èç¹û±¾ÊéûÓÐÔĶÁÍ꣬ÏëÏ´μÌÐø½Ó×ÅÔĶÁ£¬¿ÉʹÓÃÉÏ·½ "Êղص½ÎÒµÄä¯ÀÀÆ÷" ¹¦ÄÜ ºÍ "¼ÓÈëÊéÇ©" ¹¦ÄÜ£¡
¡¡¡¡¡¡¡¡¡¡1¡£¡¡¡¡Both¡¡threads¡¡wait¡£¡¡
¡¡¡¡¡¡¡¡¡¡2¡£¡¡¡¡After¡¡a¡¡1¡¡second£»¡¡thread¡¡1¡¡acquires¡¡a¡¡lock¡¡because¡¡no¡¡other¡¡thread¡¡has¡¡done¡¡so¡£¡¡
¡¡¡¡¡¡¡¡¡¡3¡£¡¡¡¡Thread¡¡1¡¡executes¡¡its¡¡code¡£¡¡
¡¡¡¡¡¡¡¡¡¡4¡£¡¡¡¡Once¡¡thread¡¡1¡¡has¡¡started¡¡executing¡¡the¡¡synchronized¡¡code£»¡¡no¡¡other¡¡code¡¡can¡¡acquire¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡the¡¡lock¡¡that¡¡is¡¡associated¡¡with¡¡the¡¡variable¡¡elements¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡5¡£¡¡¡¡When¡¡thread¡¡2¡¡wakes¡¡up¡¡after¡¡a¡¡sleep¡¡of¡¡1¡£5¡¡seconds£»¡¡it¡¡will¡¡attempt¡¡to¡¡acquire¡¡the¡¡lock£»¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡but¡¡it¡¡can¡¯t¡¡because¡¡thread¡¡1¡¡is¡¡still¡¡holding¡¡the¡¡lock¡£¡¡So¡¡the¡¡second¡¡thread¡¡must¡¡wait¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡6¡£¡¡¡¡Thread¡¡1¡¡eventually¡¡exits¡¡the¡¡synchronized¡¡code¡¡block£»¡¡allowing¡¡the¡¡second¡¡thread¡¡to¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡add¡¡an¡¡element¡¡to¡¡the¡¡collection¡£¡¡This¡¡time£»¡¡no¡¡exception¡¡is¡¡thrown¡£¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡reference¡¡to¡¡lock¡¡against¡¡does¡¡not¡¡need¡¡to¡¡be¡¡the¡¡reference¡¡that¡¡is¡¡manipulated¡¡within¡¡¡¡
the¡¡code¡¡block¡£¡¡The¡¡reference¡¡is¡¡just¡¡that£º¡¡an¡¡arbitrary¡¡reference¡£¡¡You¡¡could¡¡use¡¡a¡¡different¡¡¡¡
object¡¡instance£»¡¡and¡¡even¡¡instantiate¡¡an¡¡object¡¡like¡¡this£º¡¡
Dim¡¡_syncRoot¡¡As¡¡Object¡¡=¡¡New¡¡Object£¨£©¡¡
¡£¡¡¡£¡¡¡£¡¡
SyncLock¡¡_syncRoot¡¡
¡¡¡¡¡¡¡¡¡£¡¡¡£¡¡¡£¡¡
End¡¡SyncLock¡¡
¡¡¡¡¡¡¡¡¡¡When¡¡using¡¡exclusive¡¡blocks£»¡¡you¡¡need¡¡to¡¡use¡¡them¡¡when¡¡reading¡¡or¡¡writing¡¡the¡¡object¡£¡¡¡¡
Don¡¯t¡¡think¡¡that¡¡you¡¡need¡¡an¡¡exclusive¡¡lock¡¡only¡¡when¡¡modifying¡¡the¡¡data£»¡¡because¡¡a¡¡reader¡¡¡¡
might¡¡be¡¡reading¡¡a¡¡state¡¡that¡¡is¡¡being¡¡modified¡£¡¡As¡¡the¡¡example¡¡of¡¡the¡¡collection¡¡demonstrated£»¡¡¡¡
modifying¡¡a¡¡collection¡¡while¡¡it¡¡is¡¡being¡¡read¡¡causes¡¡an¡¡inconsistency¡¡and¡¡an¡¡exception¡£¡¡The¡¡¡¡
following¡¡code¡¡does¡¡not¡¡have¡¡a¡¡lock¡¡for¡¡the¡¡reading¡¡of¡¡the¡¡collection£»¡¡and¡¡it¡¡results¡¡in¡¡an¡¡excep
tion¡¡being¡¡thrown¡£¡¡
¡£¡¡¡£¡¡¡£¡¡
Module¡¡ThreadProblem¡¡
¡¡¡¡¡¡¡¡Dim¡¡elements¡¡As¡¡List£¨Of¡¡Integer£©¡¡=¡¡New¡¡List£¨Of¡¡Integer£©£¨£©¡¡
¡¡¡¡¡¡¡¡Sub¡¡Task1£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡item¡¡As¡¡Integer¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡For¡¡Each¡¡item¡¡In¡¡elements¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Item¡¡£¨¡¨¡¡&¡¡item¡¡&¡¡¡¨£©¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Next¡¡
¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡376¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
354¡¡¡¡¡¡¡¡¡¡¡¡¡¡CH¡¡AP¡¡T¡¡E¡¡R¡¡¡¡¡¡1¡¡3¡¡¡¡¡¡¡ö¡¡¡¡¡¡¡¡L¡¡E¡¡A¡¡R¡¡N¡¡I¡¡N¡¡G¡¡¡¡¡¡A¡¡B¡¡OU¡¡T¡¡¡¡¡¡M¡¡U¡¡L¡¡T¡¡I¡¡TH¡¡R¡¡E¡¡A¡¡DI¡¡N¡¡G¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Task2£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1500£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡SyncLock¡¡elements¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨30£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡SyncLock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Main£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨10£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨20£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread1¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task1£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread2¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task2£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread1¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread2¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Module¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Getting¡¡back¡¡to¡¡the¡¡code¡¡that¡¡worked£»¡¡it¡¡would¡¡seem¡¡that¡¡all¡¡is¡¡OK¡£¡¡From¡¡a¡¡code¡execution¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡perspective£»¡¡that¡¯s¡¡true¡£¡¡But¡¡from¡¡an¡¡execution¡efficiency¡¡perspective£»¡¡everything¡¡is¡¡not¡¡OK£»¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡because¡¡the¡¡reading¡¡of¡¡the¡¡collection¡¡is¡¡causing¡¡the¡¡writer¡¡to¡¡wait¡¡unnecessarily¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Again£»¡¡this¡¡collection¡¡example¡¡illustrates¡¡the¡¡difficulty¡¡with¡¡writing¡¡multithreaded¡¡code¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡You¡¡want¡¡to¡¡be¡¡able¡¡to¡¡add¡¡elements¡¡to¡¡a¡¡collection¡¡without¡¡needing¡¡to¡¡wait¡¡for¡¡other¡¡threads¡¡to¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡iterate¡¡a¡¡collection¡£¡¡You¡¡want¡¡to¡¡be¡¡efficient£»¡¡as¡¡well¡¡as¡¡being¡¡logically¡¡correct¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Synchronizing¡¡with¡¡Cloning¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡One¡¡way¡¡of¡¡making¡¡a¡¡lock¡¡more¡¡efficient¡¡is¡¡to¡¡clone¡¡the¡¡object¡¡so¡¡that¡¡the¡¡local¡¡copy¡¡that¡¡you¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡read¡¡from¡¡does¡¡not¡¡lock¡¡and¡¡hinder¡¡another¡¡thread¡£¡¡The¡¡two¡thread¡¡example¡¡could¡¡be¡¡rewritten¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡as¡¡follows£º¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡£¡¡¡£¡¡¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Module¡¡ThreadProblem¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡elements¡¡As¡¡List£¨Of¡¡Integer£©¡¡=¡¡New¡¡List£¨Of¡¡Integer£©£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Task1£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡items¡¡As¡¡Integer£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡SyncLock¡¡elements¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡items¡¡=¡¡elements¡£ToArray£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡SyncLock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡item¡¡As¡¡Integer¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡For¡¡Each¡¡item¡¡In¡¡items¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Item¡¡£¨¡¨¡¡&¡¡item¡¡&¡¡¡¨£©¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨&H3E8£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Next¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡377¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡C¡¡HA¡¡P¡¡TE¡¡R¡¡¡¡¡¡1¡¡3¡¡¡¡¡¡¡ö¡¡¡¡¡¡¡¡L¡¡E¡¡AR¡¡N¡¡IN¡¡G¡¡¡¡¡¡AB¡¡O¡¡U¡¡T¡¡¡¡¡¡M¡¡U¡¡L¡¡T¡¡IT¡¡HR¡¡E¡¡AD¡¡IN¡¡G¡¡355¡¡
¡¡¡¡¡¡¡¡Sub¡¡Task2£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1500£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡SyncLock¡¡elements¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨30£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡SyncLock¡¡
¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡Sub¡¡Main£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨10£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨20£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread1¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task1£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread2¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task2£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread1¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread2¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡End¡¡Sub¡¡
End¡¡Module¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡code¡¡still¡¡uses¡¡a¡¡lock£»¡¡but¡¡only¡¡in¡¡the¡¡places¡¡where¡¡it¡¡is¡¡necessary¡£¡¡When¡¡the¡¡collection¡¡¡¡
is¡¡being¡¡iterated£»¡¡the¡¡lock¡¡is¡¡applied¡¡to¡¡the¡¡operation¡¡of¡¡copying¡¡the¡¡collection¡¡to¡¡an¡¡array¡¡¡¡
£¨ToArray£¨£©£©¡£¡¡For¡¡the¡¡array¡¡iteration¡¡itself£»¡¡there¡¡is¡¡no¡¡lock¡£¡¡When¡¡writing¡¡to¡¡the¡¡collection£»¡¡there¡¡¡¡
is¡¡a¡¡lock¡£¡¡
¡¡¡¡¡¡¡¡¡¡So£»¡¡how¡¡can¡¡it¡¡be¡¡more¡¡efficient¡¡to¡¡take¡¡a¡¡snapshot¡¡of¡¡the¡¡collection£»¡¡since¡¡taking¡¡a¡¡snap
shot¡¡takes¡¡time£¿¡¡The¡¡answer¡¡is¡¡that¡¡normally¡¡it¡¡is¡¡not¡¡more¡¡efficient£»¡¡but¡¡it¡¡is¡¡more¡¡time¡slice
effective¡£¡¡
¡¡¡¡¡¡¡¡¡¡Consider¡¡a¡¡word¡¡processor¡¡that¡¡loads¡¡some¡¡text¡£¡¡When¡¡Microsoft¡¡Word¡¡loads¡¡text£»¡¡it¡¡imme
diately¡¡displays¡¡the¡¡first¡¡page£»¡¡allowing¡¡you¡¡to¡¡edit¡¡right¡¡away¡£¡¡In¡¡the¡¡background£»¡¡you¡¡see¡¡the¡¡¡¡
other¡¡pages¡¡being¡¡loaded¡¡and¡¡prepared¡¡for¡¡editing¡£¡¡Using¡¡the¡¡snapshot¡¡approach£»¡¡you¡¡get¡¡the¡¡¡¡
same¡¡effect¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡As¡¡a¡¡general¡¡threading¡¡rule£»¡¡use¡¡locks¡¡as¡¡sparingly¡¡as¡¡possible£»¡¡but¡¡use¡¡them¡¡whenever¡¡¡¡
necessary¡£¡¡If¡¡you¡¡do¡¡use¡¡them£»¡¡use¡¡them¡¡for¡¡as¡¡little¡¡code¡¡as¡¡possible¡£¡¡Locks¡¡synchronize¡¡access¡¡¡¡
to¡¡resources£»¡¡and¡¡thus¡¡only¡¡a¡¡single¡¡thread¡¡can¡¡be¡¡executing¡¡for¡¡a¡¡locked¡¡piece¡¡of¡¡code¡£¡¡The¡¡less¡¡¡¡
time¡¡code¡¡is¡¡locked£»¡¡the¡¡faster¡¡your¡¡code¡¡will¡¡be¡£¡¡
How¡¡Not¡¡to¡¡Deadlock¡¡Your¡¡Code¡¡£¨Mostly£©¡¡
A¡¡¡¡deadlock¡¡makes¡¡code¡¡stop¡¡executing¡£¡¡A¡¡deadlock¡¡occurs¡¡when¡¡one¡¡piece¡¡of¡¡code¡¡has¡¡a¡¡lock¡¡¡¡
and¡¡waits¡¡for¡¡some¡¡information¡¡to¡¡bee¡¡available¡£¡¡However£»¡¡the¡¡information¡¡does¡¡not¡¡¡¡
bee¡¡available£»¡¡because¡¡another¡¡thread¡¡that¡¡could¡¡provide¡¡that¡¡information¡¡is¡¡waiting¡¡for¡¡a¡¡¡¡
lock¡¡to¡¡bee¡¡free¡£¡¡
¡¡¡¡¡¡¡¡¡¡I¡¯ve¡¡said¡¡that¡¡if¡¡you¡¡are¡¡using¡¡locked¡¡code£»¡¡you¡¡should¡¡use¡¡it¡¡as¡¡sparingly¡¡as¡¡possible¡£¡¡That¡¯s¡¡¡¡
because¡¡using¡¡locks¡¡can¡¡lead¡¡to¡¡deadlocks¡£¡¡Deadlocks¡¡are¡¡a¡¡royal¡¡pain¡¡in¡¡the¡¡butt¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡Consider¡¡the¡¡following¡¡two¡thread¡¡collection¡¡example¡£¡¡¡¡
¡£¡¡¡£¡¡¡£¡¡
Module¡¡ThreadProblem¡¡
¡¡¡¡¡¡¡¡Dim¡¡elements¡¡As¡¡List£¨Of¡¡Integer£©¡¡=¡¡New¡¡List£¨Of¡¡Integer£©£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡378¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
356¡¡¡¡¡¡¡¡¡¡¡¡¡¡CH¡¡AP¡¡T¡¡E¡¡R¡¡¡¡¡¡1¡¡3¡¡¡¡¡¡¡ö¡¡¡¡¡¡¡¡L¡¡E¡¡A¡¡R¡¡N¡¡I¡¡N¡¡G¡¡¡¡¡¡A¡¡B¡¡OU¡¡T¡¡¡¡¡¡M¡¡U¡¡L¡¡T¡¡I¡¡TH¡¡R¡¡E¡¡A¡¡DI¡¡N¡¡G¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Task1£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡items¡¡As¡¡Integer£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡SyncLock¡¡elements¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Do¡¡While¡¡£¨elements¡£Count¡¡¡¶¡¡3£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Loop¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡items¡¡=¡¡elements¡£ToArray£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡SyncLock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡item¡¡As¡¡Integer¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡For¡¡Each¡¡item¡¡In¡¡items¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Item¡¡£¨¡¨¡¡&¡¡item¡¡&¡¡¡¨£©¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Next¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Task2£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1500£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡SyncLock¡¡elements¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨30£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡SyncLock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Main£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨10£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨20£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread1¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task1£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread2¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task2£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread1¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread2¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Module¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡The¡¡iteration¡¡code¡¡waits¡¡until¡¡the¡¡collection¡¡count¡¡is¡¡3¡£¡¡However£»¡¡this¡¡never¡¡happens£»¡¡because¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡the¡¡thread¡¡that¡¡could¡¡make¡¡the¡¡collection¡¡count¡¡3¡¡is¡¡waiting¡¡for¡¡the¡¡lock¡¡to¡¡bee¡¡free¡£¡¡The¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡bolded¡¡code¡¡is¡¡the¡¡waiting¡¡code¡¡that¡¡queries¡¡whether¡¡the¡¡collection¡¡count¡¡is¡¡3¡£¡¡If¡¡it¡¡is¡¡not£»¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread¡¡waits¡¡for¡¡1¡¡second¡¡and¡¡asks¡¡again¡£¡¡But¡¡throughout¡¡all¡¡of¡¡this¡¡waiting£»¡¡the¡¡lock¡¡is¡¡never¡¡given¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡up£»¡¡and¡¡thus¡¡the¡¡second¡¡thread¡¡that¡¡could¡¡add¡¡an¡¡element¡¡is¡¡waiting¡£¡¡The¡¡code¡¡will¡¡deadlock¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Without¡¡modifying¡¡the¡¡locks£»¡¡here¡¡is¡¡a¡¡tweak¡¡that¡¡will¡¡avoid¡¡the¡¡deadlock¡¡£¨the¡¡thread¡¡sleeps¡¡for¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡only¡¡0¡£5¡¡seconds¡¡instead¡¡of¡¡1¡£5¡¡seconds£»¡¡so¡¡the¡¡writing¡¡thread¡¡can¡¡get¡¡in¡¡first¡¡before¡¡the¡¡reader¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread¡¡gets¡¡in£©£º¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Task2£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨500£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡SyncLock¡¡elements¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨30£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡SyncLock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡379¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡C¡¡HA¡¡P¡¡TE¡¡R¡¡¡¡¡¡1¡¡3¡¡¡¡¡¡¡ö¡¡¡¡¡¡¡¡L¡¡E¡¡AR¡¡N¡¡IN¡¡G¡¡¡¡¡¡AB¡¡O¡¡U¡¡T¡¡¡¡¡¡M¡¡U¡¡L¡¡T¡¡IT¡¡HR¡¡E¡¡AD¡¡IN¡¡G¡¡357¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡single¡¡change¡¡£¨shown¡¡in¡¡bold£©¡¡makes¡¡the¡¡code¡¡work¡£¡¡In¡¡the¡¡first¡¡version£»¡¡the¡¡timing¡¡¡¡
of¡¡the¡¡code¡¡was¡¡such¡¡that¡¡the¡¡reading¡¡thread¡¡went¡¡first¡£¡¡In¡¡this¡¡version£»¡¡the¡¡writing¡¡thread¡¡goes¡¡¡¡
first¡£¡¡This¡¡shows¡¡that¡¡deadlocks¡¡are¡¡often¡¡timing¡related¡£¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡annoying¡¡part¡¡of¡¡deadlocks¡¡is¡¡that¡¡your¡¡code¡¯s¡¡behavior¡¡is¡¡not¡¡deterministic¡£¡¡Determin
istic¡¡behavior¡¡is¡¡when¡¡an¡¡action¡¡will¡¡result¡¡in¡¡a¡¡single¡¡result£»¡¡as¡¡in¡¡the¡¡case¡¡with¡¡most¡¡source¡¡¡¡
code¡£¡¡Typically£»¡¡when¡¡you¡¡have¡¡a¡¡bug£»¡¡you¡¡didn¡¯t¡¡think¡¡far¡¡enough¡¡ahead¡¡and¡¡can¡¡work¡¡through¡¡¡¡
the¡¡error¡¡systematically¡£¡¡However£»¡¡with¡¡threading£»¡¡your¡¡code¡¡ceases¡¡to¡¡be¡¡deterministic£»¡¡because¡¡¡¡
timing¡¡can¡¡change¡¡the¡¡behavior¡£¡¡Timing¡¡can¡¡be¡¡an¡¡influence¡¡in¡¡many¡¡ways£º¡¡resource¡¡swapping£»¡¡¡¡
debuggers£»¡¡microprocessor¡¡speed£»¡¡and¡¡a¡¡host¡¡of¡¡other¡¡features¡£¡¡
¡¡¡¡¡¡¡¡¡¡To¡¡make¡¡the¡¡code¡¡deterministic£»¡¡you¡¡need¡¡to¡¡fix¡¡the¡¡part¡¡of¡¡the¡¡code¡¡that¡¡hung¡¡onto¡¡the¡¡lock¡¡¡¡
when¡¡it¡¡should¡¡not¡¡have¡£¡¡Remember¡¡the¡¡cardinal¡¡rule£º¡¡keep¡¡a¡¡lock¡¡for¡¡as¡¡short¡¡a¡¡time¡¡as¡¡possible¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡You¡¡need¡¡to¡¡use¡¡a¡¡more¡¡advanced¡¡lock¡¡construct¡¡that¡¡allows¡¡you¡¡to¡¡wait¡¡for¡¡data¡¡to¡¡bee¡¡¡¡
available¡£¡¡¡¡has¡¡quite¡¡a¡¡few¡¡constructs¡¡related¡¡to¡¡threading¡¡and¡¡synchronization£»¡¡and¡¡each¡¡¡¡
construct¡¡is¡¡specific¡¡to¡¡the¡¡type¡¡of¡¡problem¡¡you¡¡are¡¡trying¡¡to¡¡solve¡£¡¡In¡¡the¡¡case¡¡of¡¡a¡¡deadlock£»¡¡you¡¡¡¡
want¡¡to¡¡use¡¡the¡¡Monitor¡¡type¡£¡¡The¡¡Monitor¡¡type¡¡is¡¡an¡¡advanced¡¡synchronization¡¡type¡¡that¡¡allows¡¡¡¡
locking¡¡and¡¡pulsing¡¡of¡¡trigger¡¡signals¡¡for¡¡those¡¡threads¡¡that¡¡are¡¡waiting¡£¡¡
¡¡¡¡¡¡¡¡¡¡Let¡¯s¡¡return¡¡to¡¡our¡¡multiple¡¡cooks¡¡in¡¡the¡¡kitchen¡¡analogy¡£¡¡Say¡¡one¡¡cook¡¡needs¡¡a¡¡particular¡¡¡¡
fish¡¡pan£»¡¡which¡¡is¡¡already¡¡being¡¡used¡¡by¡¡another¡¡cook¡£¡¡Does¡¡the¡¡waiting¡¡cook¡¡tap¡¡her¡¡foot¡¡beside¡¡¡¡
the¡¡cook¡¡doing¡¡the¡¡cooking£¿¡¡Or¡¡does¡¡the¡¡waiting¡¡cook¡¡do¡¡something¡¡else¡¡and¡¡ask¡¡the¡¡cook¡¡using¡¡¡¡
the¡¡pan¡¡to¡¡inform¡¡h
¿ì½Ý²Ù×÷: °´¼üÅÌÉÏ·½Ïò¼ü ¡û »ò ¡ú ¿É¿ìËÙÉÏÏ·ҳ °´¼üÅÌÉ쵀 Enter ¼ü¿É»Øµ½±¾ÊéĿ¼ҳ °´¼üÅÌÉÏ·½Ïò¼ü ¡ü ¿É»Øµ½±¾Ò³¶¥²¿!
ÎÂÜ°Ìáʾ£º ο´Ð¡ËµµÄͬʱ·¢±íÆÀÂÛ£¬Ëµ³ö×Ô¼ºµÄ¿´·¨ºÍÆäËüС»ï°éÃÇ·ÖÏíÒ²²»´íŶ£¡·¢±íÊéÆÀ»¹¿ÉÒÔ»ñµÃ»ý·ÖºÍ¾Ñé½±Àø£¬ÈÏÕæдԴ´ÊéÆÀ ±»²ÉÄÉΪ¾«ÆÀ¿ÉÒÔ»ñµÃ´óÁ¿½ð±Ò¡¢»ý·ÖºÍ¾Ñé½±ÀøŶ£¡