ÓÑÇéÌáʾ£ºÈç¹û±¾ÍøÒ³´ò¿ªÌ«Âý»òÏÔʾ²»ÍêÕû£¬Çë³¢ÊÔÊó±êÓÒ¼ü¡°Ë¢Ð¡±±¾ÍøÒ³£¡
¸»Ê¿¿µÐ¡ËµÍø ·µ»Ø±¾ÊéĿ¼ ¼ÓÈëÊéÇ© ÎÒµÄÊé¼Ü ÎÒµÄÊéÇ© TXTÈ«±¾ÏÂÔØ ¡ºÊղص½ÎÒµÄä¯ÀÀÆ÷¡»

VB2008´ÓÈëÃŵ½¾«Í¨(PDF¸ñʽӢÎÄ°æ)-µÚ67²¿·Ö

¿ì½Ý²Ù×÷: °´¼üÅÌÉÏ·½Ïò¼ü ¡û »ò ¡ú ¿É¿ìËÙÉÏÏ·­Ò³ °´¼üÅÌÉ쵀 Enter ¼ü¿É»Øµ½±¾ÊéĿ¼ҳ °´¼üÅÌÉÏ·½Ïò¼ü ¡ü ¿É»Øµ½±¾Ò³¶¥²¿! Èç¹û±¾ÊéûÓÐÔĶÁÍ꣬ÏëÏ´μÌÐø½Ó×ÅÔĶÁ£¬¿ÉʹÓÃÉÏ·½ "Êղص½ÎÒµÄä¯ÀÀÆ÷" ¹¦ÄÜ ºÍ "¼ÓÈëÊéÇ©" ¹¦ÄÜ£¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡You¡¡need¡¡to¡¡instantiate¡¡a¡¡single¡¡ThreadedTask¡¡and¡¡associate¡¡it¡¡with¡¡a¡¡single¡¡Thread¡¡instance£»¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡like¡¡this£º¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡task1¡¡As¡¡ThreadedTask¡¡=¡¡New¡¡ThreadedTask£¨¡¨hello¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡task2¡¡As¡¡ThreadedTask¡¡=¡¡New¡¡ThreadedTask£¨¡¨goodbye¡¨£©¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread1¡¡As¡¡Thread¡¡=¡¡New¡¡Thread£¨AddressOf¡¡task1¡£MethodToRun£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread2¡¡As¡¡Thread¡¡=¡¡New¡¡Thread£¨AddressOf¡¡task2¡£MethodToRun£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread1¡£Start£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread2¡£Start£¨£©¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡If¡¡you¡¡are¡¡running¡¡a¡¡stateful¡¡method£»¡¡you¡¡need¡¡to¡¡associate¡¡a¡¡task¡¡instance¡¡with¡¡a¡¡thread¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡instance¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Using¡¡a¡¡Thread¡¡Parameter¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Suppose¡¡that¡¡you¡¡want¡¡to¡¡create¡¡a¡¡stateful¡¡thread¡£¡¡You¡¡can¡¡do¡¡this¡¡by¡¡using¡¡a¡¡thread¡¡parameter¡£¡¡In¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡other¡¡words£»¡¡the¡¡method¡¡that¡¡you¡¡invoke¡¡on¡¡another¡¡thread¡¡takes¡¡a¡¡parameter¡£¡¡Here¡¯s¡¡an¡¡example£º¡¡


¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­Page¡¡371¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡349¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡SimpleThreadWithStateTask£¨ByVal¡¡buffer¡¡As¡¡Object£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨You¡¡said¡¡£¨¡¨¡¡&¡¡buffer¡£ToString£¨£©¡¡&¡¡¡¨£©¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Private¡¡Sub¡¡SimpleThreadWithState£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread1¡¡As¡¡New¡¡Thread£¨AddressOf¡¡SimpleThreadWithStateTask£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread1¡£Start£¨¡¨my¡¡text¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡¡¡



¡¡¡¡¡¡¡¡¡¡The¡¡major¡¡difference¡¡with¡¡a¡¡thread¡¡parameter¡¡is¡¡that¡¡you¡¡declare¡¡the¡¡function¡¡that¡¡is¡¡executed¡¡¡¡

with¡¡a¡¡parameter£»¡¡and¡¡the¡¡¡¡Start£¨£©¡¡method¡¡has¡¡a¡¡parameter¡£¡¡¡¡

¡¡¡¡¡¡¡¡¡¡Two¡¡restrictions¡¡apply¡¡to¡¡using¡¡a¡¡thread¡¡parameter£º¡¡you¡¡can¡¡send¡¡only¡¡a¡¡single¡¡parameter£»¡¡¡¡

and¡¡that¡¡parameter¡¡must¡¡be¡¡an¡¡object¡£¡¡



Synchronizing¡¡Between¡¡Threads¡¡



When¡¡you¡¡have¡¡two¡¡threads¡¡and¡¡both¡¡share¡¡state¡¡£¨such¡¡as¡¡a¡¡variable£©£»¡¡a¡¡concurrency¡¡situation¡¡¡¡

may¡¡arise¡£¡¡Sharing¡¡state¡¡between¡¡two¡¡independent¡¡threads¡¡is¡¡not¡¡a¡¡problem¡¡if¡¡both¡¡threads¡¡¡¡

consider¡¡the¡¡data¡¡as¡¡read¡­only¡£¡¡What¡¡does¡¡the¡¡reading¡¡thread¡¡read£¿¡¡Is¡¡the¡¡state¡¡consistent£¿¡¡It¡¡is¡¡¡¡

probably¡¡not¡¡consistent£»¡¡and¡¡that¡¡is¡¡why¡¡you¡¡need¡¡to¡¡synchronize¡¡access¡¡to¡¡state¡£¡¡

¡¡¡¡¡¡¡¡¡¡Let¡¯s¡¡consider¡¡a¡¡simple¡¡¡¡collection¡¡class¡¡example¡£¡¡The¡¡following¡¡source¡¡code¡¡executes¡¡¡¡

in¡¡the¡¡calling¡¡thread£»¡¡instantiates¡¡a¡¡list¡¡collection£»¡¡and¡¡then¡¡adds¡¡two¡¡numbers¡¡to¡¡the¡¡collection¡£¡¡



Dim¡¡elements¡¡As¡¡List£¨Of¡¡Integer£©=¡¡New¡¡List£¨Of¡¡Integer£©£¨£©¡¡

elements¡£Add£¨10£©¡¡

elements¡£Add£¨20£©¡¡



¡¡¡¡¡¡¡¡¡¡In¡¡the¡¡next¡¡step£»¡¡we¡¡define¡¡a¡¡method¡¡that¡¡iterates¡¡the¡¡elements¡¡collection¡¡£¨which¡¡is¡¡declared¡¡at¡¡¡¡

a¡¡higher¡¡scope£©¡£¡¡



Sub¡¡Task1£¨£©¡¡

¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡

¡¡¡¡¡¡¡¡Dim¡¡item¡¡As¡¡Integer¡¡

¡¡¡¡¡¡¡¡For¡¡Each¡¡item¡¡In¡¡elements¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Item¡¡£¨¡¨¡¡&¡¡item¡¡&¡¡¡¨£©¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡

¡¡¡¡¡¡¡¡Next¡¡

End¡¡Sub¡¡¡¡



¡¡¡¡¡¡¡¡¡¡This¡¡thread¡¡iterates¡¡the¡¡data£»¡¡and¡¡the¡¡two¡¡Thread¡£Sleep£¨£©¡¡calls¡¡put¡¡the¡¡threads¡¡to¡¡sleep¡¡for¡¡¡¡

1000¡¡milliseconds£»¡¡or¡¡1¡¡second¡£¡¡By¡¡putting¡¡the¡¡thread¡¡to¡¡sleep£»¡¡we¡¡can¡¡artificially¡¡construct¡¡a¡¡¡¡

situation¡¡where¡¡another¡¡thread¡¡adds¡¡to¡¡the¡¡collection¡¡while¡¡the¡¡collection¡¡is¡¡being¡¡iterated¡£¡¡¡¡

¡¡¡¡¡¡¡¡¡¡The¡¡method¡¡that¡¡adds¡¡an¡¡element¡¡to¡¡the¡¡collection¡¡is¡¡defined¡¡as¡¡follows£º¡¡



Sub¡¡Task2£¨£©¡¡

¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1500£©¡¡

¡¡¡¡¡¡¡¡elements¡£Add£¨30£©¡¡

End¡¡Sub¡¡


¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­Page¡¡372¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­

350¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡The¡¡Task1£¨£©¡¡and¡¡Task2£¨£©¡¡methods¡¡are¡¡started¡¡in¡¡separate¡¡threads¡¡as¡¡follows£º£º¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨10£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨20£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread1¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task1£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread2¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task2£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread1¡£Start£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread2¡£Start£¨£©¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Running¡¡the¡¡threaded¡¡code¡¡will¡¡generate¡¡an¡¡exception£»¡¡but¡¡not¡¡immediately¡£¡¡First£»¡¡the¡¡caller¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread¡¡creates¡¡and¡¡starts¡¡thread1¡¡and¡¡thread2¡£¡¡thread1¡¡goes¡¡to¡¡sleep¡¡for¡¡1¡¡second£»¡¡and¡¡thread2¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡goes¡¡to¡¡sleep¡¡for¡¡1¡£5¡¡seconds¡£¡¡After¡¡thread1¡¡awakens£»¡¡one¡¡item¡¡in¡¡the¡¡collection¡¡is¡¡iterated£»¡¡and¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread1¡¡goes¡¡to¡¡sleep¡¡for¡¡another¡¡second¡£¡¡But¡¡before¡¡thread1¡¡reawakens£»¡¡thread2¡¡awakens¡¡and¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡adds¡¡an¡¡element¡¡to¡¡the¡¡collection¡£¡¡When¡¡thread1¡¡reawakens¡¡and¡¡attempts¡¡to¡¡iterate¡¡another¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡element¡¡in¡¡the¡¡collection£»¡¡an¡¡exception¡¡is¡¡generated£»¡¡as¡¡shown¡¡in¡¡Figure¡¡13¡­4¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Figure¡¡13¡­4¡£¡¡Exception¡¡thrown¡¡after¡¡adding¡¡element¡¡to¡¡the¡¡collection£»¡¡as¡¡shown¡¡in¡¡the¡¡Visual¡¡Basic¡¡IDE¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡The¡¡InvalidOperationException¡¡is¡¡thrown¡¡to¡¡indicate¡¡that¡¡you¡¡can¡¯t¡¡add¡¡elements¡¡to¡¡a¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡collection¡¡while¡¡iterating¡¡a¡¡collection¡£¡¡The¡¡collection¡¡classes¡¡think¡¡it¡¡is¡¡a¡¡bad¡¡idea¡¡to¡¡modify¡¡and¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡iterate¡¡a¡¡collection¡¡at¡¡the¡¡same¡¡time¡£¡¡I¡¡agree¡¡with¡¡the¡¡collection¡¡classes£»¡¡because¡¡doing¡¡so¡¡could¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡give¡¡unpredictable¡¡results¡£¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡The¡¡problem¡¡in¡¡the¡¡source¡¡code¡¡is¡¡how¡¡to¡¡use¡¡the¡¡collection¡¡classes¡¡in¡¡a¡¡multithreaded¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡context¡£¡¡In¡¡the¡¡example£»¡¡items¡¡are¡¡added¡¡to¡¡the¡¡collection¡¡while¡¡the¡¡collection¡¡is¡¡being¡¡iterated¡£¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡A¡¡monly¡¡suggested¡¡approach¡¡is¡¡to¡¡use¡¡the¡¡type¡¡¡¡System¡£Collections¡£ObjectModel¡£¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ReadOnlyCollection£»¡¡as¡¡in¡¡the¡¡following¡¡example¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Imports¡¡System¡£Collections¡£ObjectModel¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Imports¡¡System¡£Threading¡¡


¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­Page¡¡373¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡351¡¡



Module¡¡ThreadProblem¡¡

¡¡¡¡¡¡¡¡Dim¡¡elements¡¡As¡¡List£¨Of¡¡Integer£©¡¡=¡¡New¡¡List£¨Of¡¡Integer£©£¨£©¡¡



¡¡¡¡¡¡¡¡Sub¡¡Task1£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡item¡¡As¡¡Integer¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡listElements¡¡As¡¡New¡¡ReadOnlyCollection£¨Of¡¡Integer£©£¨elements£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡For¡¡Each¡¡item¡¡In¡¡listElements¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Item¡¡£¨¡¨¡¡&¡¡item¡¡&¡¡¡¨£©¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Next¡¡

¡¡¡¡¡¡¡¡End¡¡Sub¡¡



¡¡¡¡¡¡¡¡Sub¡¡Task2£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1500£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨30£©¡¡

¡¡¡¡¡¡¡¡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¡¡change¡¡is¡¡the¡¡bolded¡¡code£»¡¡which¡¡instantiates¡¡the¡¡type¡¡System¡£Collections¡£¡¡

ReadOnlyCollection£»¡¡to¡¡which¡¡we¡¡pass¡¡the¡¡elements¡¡list¡£¡¡The¡¡ReadOnlyCollection¡¡provides¡¡the¡¡¡¡

base¡¡class¡¡for¡¡a¡¡generic¡¡read¡­only¡¡collection¡£¡¡The¡¡For¡¡Each¡¡iterator¡¡then¡¡iterates¡¡a¡¡collection¡¡¡¡

that¡¡is¡¡read¡­only£»¡¡but¡¡based¡¡on¡¡the¡¡original¡¡collection¡£¡¡However£»¡¡running¡¡the¡¡code¡¡will¡¡result¡¡in¡¡¡¡

the¡¡same¡¡exception¡£¡¡This¡¡demonstrates¡¡that¡¡ReadOnlyCollection¡¡does¡¡not¡¡take¡¡a¡¡snapshot£»¡¡but¡¡¡¡

masks¡¡the¡¡collection¡£¡¡The¡¡mask¡¡disables¡¡the¡¡addition¡¡of¡¡items¡¡to¡¡the¡¡collection£»¡¡but¡¡because¡¡the¡¡¡¡

other¡¡thread¡¡is¡¡taking¡¡a¡¡shortcut¡¡and¡¡editing¡¡the¡¡original¡¡collection£»¡¡the¡¡read¡­only¡¡collection¡¡is¡¡¡¡

modified¡¡as¡¡well¡£¡¡¡¡

¡¡¡¡¡¡¡¡¡¡Let¡¯s¡¡say¡¡that¡¡converting¡¡the¡¡collection¡¡into¡¡a¡¡read¡­only¡¡collection¡¡had¡¡worked¡£¡¡It¡¡would¡¡¡¡

not¡¡have¡¡solved¡¡anything¡£¡¡A¡¡read¡­only¡¡collection¡¡means¡¡that¡¡the¡¡second¡¡thread¡¡would¡¡generate¡¡¡¡

an¡¡exception¡¡because¡¡you¡¡can¡¯t¡¡add¡¡elements¡¡to¡¡a¡¡collection¡¡that¡¡is¡¡read¡­only¡£¡¡The¡¡point¡¡is¡¡that¡¡¡¡

when¡¡writing¡¡multithreaded¡¡code¡¡that¡¡shares¡¡variables£»¡¡you¡¡don¡¯t¡¡have¡¡an¡¡easy¡¡solution£»¡¡because¡¡¡¡

you¡¡are¡¡trying¡¡to¡¡solve¡¡the¡¡problem¡¡of¡¡how¡¡to¡¡keep¡¡multiple¡¡cooks¡¡productive¡¡in¡¡a¡¡single¡¡kitchen¡£¡¡

¡¡¡¡¡¡¡¡¡¡We¡¡are¡¡trying¡¡to¡¡solve¡¡a¡¡classic¡¡reader/writer¡¡problem£»¡¡where¡¡some¡¡threads¡¡are¡¡interested¡¡¡¡

only¡¡in¡¡reading¡¡the¡¡data£»¡¡and¡¡other¡¡threads¡¡are¡¡interested¡¡only¡¡in¡¡modifying¡¡the¡¡data¡£¡¡One¡¡way¡¡¡¡

to¡¡synchronize¡¡the¡¡readers¡¡and¡¡writers¡¡is¡¡to¡¡use¡¡an¡¡exclusive¡¡lock£»¡¡so¡¡that¡¡only¡¡one¡¡thread¡¡may¡¡¡¡

read¡¡or¡¡write¡£¡¡


¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­Page¡¡374¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­

352¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Using¡¡Exclusive¡¡Locks¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡When¡¡using¡¡exclusive¡¡locks¡¡in¡¡£»¡¡you¡¡are¡¡saying£»¡¡¡°Only¡¡one¡¡thread¡¡may¡¡execute¡¡this¡¡piece¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡of¡¡code¡£¡±¡¡If¡¡two¡¡threads¡¡want¡¡to¡¡execute¡¡a¡¡particular¡¡piece¡¡of¡¡code£»¡¡one¡¡will¡¡be¡¡granted¡¡access£»¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡while¡¡the¡¡other¡¡thread¡¡waits¡¡until¡¡the¡¡granted¡¡thread¡¡has¡¡exited¡¡the¡¡code¡¡block¡£¡¡It¡¡is¡¡important¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡to¡¡understand¡¡that¡¡an¡¡exclusive¡¡lock¡¡grants¡¡access¡¡to¡¡code£»¡¡not¡¡data£»¡¡but¡¡that¡¡code¡¡could¡¡access¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡data¡£¡¡And¡¡because¡¡only¡¡one¡¡thread¡¡is¡¡accessing¡¡the¡¡code£»¡¡it¡¡is¡¡implied¡¡that¡¡only¡¡one¡¡thread¡¡can¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡access¡¡the¡¡data¡£¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡The¡¡following¡¡is¡¡an¡¡example¡¡of¡¡code¡¡that¡¡uses¡¡exclusive¡¡locks¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡£¡¡¡£¡¡¡£¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Module¡¡ThreadProblem¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡elements¡¡As¡¡List£¨Of¡¡Integer£©¡¡=¡¡New¡¡List£¨Of¡¡Integer£©£¨£©¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Task1£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡SyncLock¡¡elements¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡item¡¡As¡¡Integer¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡For¡¡Each¡¡item¡¡In¡¡elements¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Item¡¡£¨¡¨¡¡&¡¡item¡¡&¡¡¡¨£©¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Next¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡SyncLock¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡bolded¡¡lines¡¡use¡¡the¡¡SyncLock¡¡and¡¡End¡¡SyncLock¡¡keywords£»¡¡which¡¡represent¡¡a¡¡code¡¡block¡¡of¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡exclusive¡¡access¡£¡¡The¡¡thread¡¡is¡¡granted¡¡access¡¡to¡¡only¡¡a¡¡single¡¡code¡¡block¡¡in¡¡each¡¡instance¡£¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Looking¡¡at¡¡the¡¡code¡¡within¡¡the¡¡block£»¡¡you¡¡can¡¡see¡¡that¡¡the¡¡collection¡¡is¡¡accessed¡¡in¡¡two¡¡locations¡£¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Using¡¡the¡¡exclusive¡¡SyncLock¡¡argument¡¡where¡¡a¡¡single¡¡thread¡¡can¡¡access¡¡only¡¡a¡¡single¡¡code¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡block£»¡¡one¡¡thread¡¡will¡¡write¡¡to¡¡the¡¡collection£»¡¡and¡¡another¡¡thread¡¡will¡¡read¡¡from¡¡the¡¡collection¡£¡¡


¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­Page¡¡375¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡353¡¡



¡¡¡¡¡¡¡¡¡¡The¡¡SyncLock¡¡statement¡¡has¡¡a¡¡parameter¡¡that¡¡is¡¡a¡¡reference¡¡to¡¡lock¡¡against¡£¡¡In¡¡both¡¡threads£»¡¡¡¡

the¡¡reference¡¡is¡¡elements¡£¡¡The¡¡mon¡¡reference¡¡synchronizes¡¡access¡¡to¡¡code¡£¡¡At¡¡any¡¡given¡¡¡¡

point¡¡in¡¡time£»¡¡the¡¡code¡¡contained¡¡within¡¡the¡¡SyncLock¡¡block¡¡will¡¡have¡¡only¡¡a¡¡single¡¡thread¡¡¡¡

executing¡£¡¡This¡¡implements¡¡the¡¡desired¡¡feature£»¡¡where¡¡only¡¡one¡¡thread¡¡is¡¡accessing¡¡code¡¡that¡¡¡¡

reads¡¡or¡¡writes¡¡to¡¡the¡¡collection¡£¡¡The¡¡flow¡¡of¡¡the¡¡program¡¡is¡¡as¡¡follows£º¡¡



¡¡¡¡¡¡¡¡¡¡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¡¡£¨
·µ»ØĿ¼ ÉÏÒ»Ò³ ÏÂÒ»Ò³ »Øµ½¶¥²¿ ÔÞ£¨11£© ²È£¨11£©
¿ì½Ý²Ù×÷: °´¼üÅÌÉÏ·½Ïò¼ü ¡û »ò ¡ú ¿É¿ìËÙÉÏÏ·­Ò³ °´¼üÅÌÉ쵀 Enter ¼ü¿É»Øµ½±¾ÊéĿ¼ҳ °´¼üÅÌÉÏ·½Ïò¼ü ¡ü ¿É»Øµ½±¾Ò³¶¥²¿!
ÎÂÜ°Ìáʾ£º ο´Ð¡ËµµÄͬʱ·¢±íÆÀÂÛ£¬Ëµ³ö×Ô¼ºµÄ¿´·¨ºÍÆäËüС»ï°éÃÇ·ÖÏíÒ²²»´íŶ£¡·¢±íÊéÆÀ»¹¿ÉÒÔ»ñµÃ»ý·ÖºÍ¾­Ñé½±Àø£¬ÈÏÕæдԭ´´ÊéÆÀ ±»²ÉÄÉΪ¾«ÆÀ¿ÉÒÔ»ñµÃ´óÁ¿½ð±Ò¡¢»ý·ÖºÍ¾­Ñé½±ÀøŶ£¡