VB2008´ÓÈëÃŵ½¾«Í¨(PDF¸ñʽӢÎÄ°æ)-µÚ103²¿·Ö
°´¼üÅÌÉÏ·½Ïò¼ü ¡û »ò ¡ú ¿É¿ìËÙÉÏÏ·ҳ£¬°´¼üÅÌÉ쵀 Enter ¼ü¿É»Øµ½±¾ÊéĿ¼ҳ£¬°´¼üÅÌÉÏ·½Ïò¼ü ¡ü ¿É»Øµ½±¾Ò³¶¥²¿£¡
¡ª¡ª¡ª¡ªÎ´ÔĶÁÍꣿ¼ÓÈëÊéÇ©ÒѱãÏ´μÌÐøÔĶÁ£¡
¡¡¡¡¡¡¡¡¡¡Let¡¯s¡¡look¡¡at¡¡a¡¡collection¡¡example¡¡that¡¡has¡¡four¡¡threads£º¡¡three¡¡readers¡¡and¡¡one¡¡writer¡£¡¡The¡¡¡¡
example¡¡uses¡¡Thread¡£Sleep£¨£©¡¡strategically£»¡¡so¡¡that¡¡you¡¡can¡¡see¡¡how¡¡a¡¡reader¡¡thread¡¡and¡¡writer¡¡¡¡
thread¡¡interact¡¡with¡¡each¡¡other¡£¡¡
Imports¡¡System¡£Threading¡¡
Friend¡¡Module¡¡TestMoreTopics¡¡
¡¡¡¡¡¡¡¡Private¡¡rwlock¡¡As¡¡New¡¡ReaderWriterLock£¨£©¡¡
¡¡¡¡¡¡¡¡Private¡¡elements¡¡As¡¡New¡¡List£¨Of¡¡Integer£©£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡382¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
360¡¡¡¡¡¡¡¡¡¡¡¡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£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡1¡¡waiting¡¡for¡¡read¡¡lock¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£AcquireReaderLock£¨¡1£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡1¡¡has¡¡read¡¡lock¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡item¡¡As¡¡Integer¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡For¡¡Each¡¡item¡¡In¡¡elements¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡1¡¡Item¡¡£¨¡¨¡¡&¡¡item¡¡&¡¡¡¨£©¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Next¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡1¡¡releasing¡¡read¡¡lock¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£ReleaseLock£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Task2£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1250£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡2¡¡waiting¡¡for¡¡read¡¡lock¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£AcquireReaderLock£¨¡1£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡2¡¡has¡¡read¡¡lock¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡item¡¡As¡¡Integer¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡For¡¡Each¡¡item¡¡In¡¡elements¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡2¡¡Item¡¡£¨¡¨¡¡&¡¡item¡¡&¡¡¡¨£©¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Next¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡2¡¡releasing¡¡read¡¡lock¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£ReleaseLock£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Task3£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1750£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡3¡¡waiting¡¡for¡¡read¡¡lock¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£AcquireReaderLock£¨¡1£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡3¡¡has¡¡read¡¡lock¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡item¡¡As¡¡Integer¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡For¡¡Each¡¡item¡¡In¡¡elements¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡3¡¡Item¡¡£¨¡¨¡¡&¡¡item¡¡&¡¡¡¨£©¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Next¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡3¡¡releasing¡¡read¡¡lock¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£ReleaseLock£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Task4£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1500£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡4¡¡waiting¡¡for¡¡write¡¡lock¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£AcquireWriterLock£¨¡1£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡4¡¡has¡¡write¡¡Lock¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡383¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡361¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨30£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡4¡¡releasing¡¡write¡¡lock¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£ReleaseLock£¨£©¡¡
¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡Private¡¡Sub¡¡ReaderWriter£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨10£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨20£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread1¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task1£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread2¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task2£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread3¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task3£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread4¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task4£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread1¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread2¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread3¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread4¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡Public¡¡Sub¡¡RunAll£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡TestMoreTopics¡£ReaderWriter£¨£©¡¡
¡¡¡¡¡¡¡¡End¡¡Sub¡¡
End¡¡Module¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡bolded¡¡code¡¡contains¡¡all¡¡of¡¡the¡¡references¡¡to¡¡the¡¡reader/writer¡¡¡¡class¡¡imple
mentation¡£¡¡Unlike¡¡the¡¡keyword¡¡SyncLock¡¡or¡¡the¡¡type¡¡Monitor£»¡¡the¡¡ReaderWriterLock¡¡type¡¡is¡¡¡¡
instantiated¡¡and¡¡the¡¡instance¡¡is¡¡shared¡¡between¡¡threads¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡code¡¡to¡¡acquire¡¡a¡¡reader¡¡lock¡¡or¡¡writer¡¡lock¡¡has¡¡a¡¡parameter¡¡of¡¡value¡¡¡¡¡1£»¡¡which¡¡means¡¡¡¡
to¡¡wait¡¡until¡¡the¡¡lock¡¡is¡¡acquired¡£¡¡A¡¡positive¡¡value¡¡means¡¡to¡¡wait¡¡for¡¡a¡¡number¡¡of¡¡milliseconds£»¡¡and¡¡¡¡
if¡¡the¡¡lock¡¡has¡¡not¡¡been¡¡acquired£»¡¡then¡¡return¡¡from¡¡the¡¡method¡¡call¡£¡¡If¡¡you¡¡do¡¡use¡¡a¡¡timeout£»¡¡before¡¡¡¡
you¡¡attempt¡¡to¡¡manipulate¡¡shared¡¡code£»¡¡you¡¡need¡¡to¡¡reference¡¡the¡¡property¡¡IsReaderLockHeld¡¡or¡¡¡¡
IsWriterLockHeld¡¡to¡¡ensure¡¡that¡¡you¡¡have¡¡acquired¡¡the¡¡lock¡£¡¡In¡¡the¡¡reader¡¡threads£»¡¡after¡¡having¡¡¡¡
acquired¡¡the¡¡reader¡¡locks£»¡¡the¡¡items¡¡are¡¡iterated¡£¡¡¡¡
¡öNote¡¡¡¡The¡¡example¡¡seems¡¡to¡¡break¡¡the¡¡rule¡¡regarding¡¡keeping¡¡locks¡¡for¡¡as¡¡short¡¡a¡¡time¡¡possible£»¡¡since¡¡it¡¡¡¡
holds¡¡onto¡¡the¡¡lock¡¡while¡¡iterating¡£¡¡In¡¡the¡¡case¡¡of¡¡a¡¡reader/writer¡¡implementation£»¡¡you¡¡have¡¡a¡¡unique¡¡situation¡¡¡¡
in¡¡that¡¡you¡¡should¡¡be¡¡manipulating¡¡data¡¡that¡¡is¡¡mostly¡¡to¡¡be¡¡read£»¡¡which¡¡implies¡¡that¡¡most¡¡of¡¡the¡¡time£»¡¡you¡¡will¡¡¡¡
be¡¡treating¡¡the¡¡shared¡¡data¡¡as¡¡read¡only¡£¡¡For¡¡those¡¡times¡¡when¡¡you¡¡are¡¡writing¡¡to¡¡the¡¡shared¡¡data£»¡¡it¡¡is¡¡fine¡¡if¡¡the¡¡¡¡
thread¡¡must¡¡wait¡¡a¡¡moment¡¡or¡¡two¡£¡¡A¡¡reader/writer¡¡lock¡¡does¡¡not¡¡make¡¡sense¡¡if¡¡you¡¡do¡¡not¡¡have¡¡data¡¡that¡¡is¡¡essen
tially¡¡read¡only¡£¡¡In¡¡other¡¡situations£»¡¡you¡¡should¡¡use¡¡the¡¡Monitor¡¡approach£»¡¡as¡¡described¡¡in¡¡the¡¡previous¡¡section¡£¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡example¡¡demonstrates¡¡handling¡¡data¡¡that¡¡is¡¡mostly¡¡to¡¡be¡¡read£»¡¡since¡¡it¡¡has¡¡three¡¡threads¡¡¡¡
reading¡¡and¡¡one¡¡thread¡¡writing¡£¡¡It¡¡is¡¡important¡¡to¡¡make¡¡sure¡¡that¡¡you¡¡don¡¯t¡¡end¡¡up¡¡writing¡¡while¡¡¡¡
holding¡¡a¡¡read¡only¡¡lock¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡384¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
362¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Running¡¡the¡¡code¡¡results¡¡in¡¡the¡¡following¡¡output¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡1¡¡waiting¡¡for¡¡read¡¡lock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡1¡¡has¡¡read¡¡lock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡1¡¡Item¡¡£¨10£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡2¡¡waiting¡¡for¡¡read¡¡lock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡2¡¡has¡¡read¡¡lock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡2¡¡Item¡¡£¨10£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡4¡¡waiting¡¡for¡¡write¡¡lock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡3¡¡waiting¡¡for¡¡read¡¡lock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡1¡¡Item¡¡£¨20£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡2¡¡Item¡¡£¨20£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡1¡¡releasing¡¡read¡¡lock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡2¡¡releasing¡¡read¡¡lock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡4¡¡has¡¡write¡¡Lock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡4¡¡releasing¡¡write¡¡lock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡3¡¡has¡¡read¡¡lock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡3¡¡Item¡¡£¨10£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡3¡¡Item¡¡£¨20£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡3¡¡Item¡¡£¨30£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡3¡¡releasing¡¡read¡¡lock¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡In¡¡the¡¡generated¡¡output£»¡¡the¡¡sequence¡¡of¡¡events¡¡is¡¡as¡¡follows£º¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡1¡£¡¡¡¡Thread¡¡1¡¡wants¡¡and¡¡acquires¡¡a¡¡read¡only¡¡lock¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡2¡£¡¡¡¡Thread¡¡1¡¡outputs¡¡the¡¡first¡¡number¡¡in¡¡the¡¡collection¡£¡¡Thread¡¡1¡¡then¡¡sleeps£»¡¡which¡¡lets¡¡in¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡another¡¡thread¡¡for¡¡execution¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡3¡£¡¡¡¡Thread¡¡2¡¡wants¡¡and¡¡acquires¡¡another¡¡read¡only¡¡lock¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡4¡£¡¡¡¡Thread¡¡2¡¡outputs¡¡the¡¡first¡¡number¡¡in¡¡the¡¡collection¡£¡¡Thread¡¡2¡¡then¡¡sleeps£»¡¡which¡¡lets¡¡in¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡another¡¡thread¡¡for¡¡execution¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡5¡£¡¡¡¡Thread¡¡4¡¡wants¡¡a¡¡writer¡¡lock¡¡and¡¡is¡¡kept¡¡on¡¡hold¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡6¡£¡¡¡¡Thread¡¡3¡¡wants¡¡a¡¡read¡only¡¡lock£»¡¡but¡¡because¡¡thread¡¡4¡¡has¡¡asked¡¡for¡¡a¡¡writer¡¡lock¡¡and¡¡is¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡queued£»¡¡thread¡¡3¡¡is¡¡put¡¡on¡¡hold¡£¡¡At¡¡this¡¡step£»¡¡threads¡¡3¡¡and¡¡4¡¡are¡¡put¡¡on¡¡hold¡¡and¡¡are¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡waiting¡¡for¡¡the¡¡read¡only¡¡locks¡¡of¡¡threads¡¡1¡¡and¡¡2¡¡to¡¡be¡¡released¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡7¡£¡¡¡¡Threads¡¡1¡¡and¡¡2¡¡output¡¡the¡¡remaining¡¡numbers¡¡in¡¡the¡¡collection¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡8¡£¡¡¡¡Threads¡¡1¡¡and¡¡2¡¡release¡¡the¡¡read¡only¡¡locks¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡9¡£¡¡¡¡Thread¡¡4¡¡is¡¡given¡¡a¡¡writer¡¡lock£»¡¡and¡¡thread¡¡3¡¡is¡¡still¡¡on¡¡hold¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡10¡£¡¡¡¡Thread¡¡4¡¡writes¡¡to¡¡the¡¡collection¡¡and¡¡releases¡¡the¡¡writer¡¡lock¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡11¡£¡¡¡¡Thread¡¡3¡¡acquires¡¡a¡¡read¡only¡¡lock¡¡and¡¡iterates¡¡the¡¡individual¡¡numbers£»¡¡including¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡number¡¡added¡¡by¡¡thread¡¡4¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡385¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡363¡¡
¡¡¡¡¡¡¡¡¡¡Notice¡¡that¡¡the¡¡reader/writer¡¡lock¡¡makes¡¡the¡¡sequence¡¡of¡¡reading¡¡and¡¡writing¡¡events¡¡orderly£»¡¡¡¡
so¡¡that¡¡the¡¡shared¡¡state¡¡is¡¡always¡¡consistent¡£¡¡The¡¡reader/writer¡¡lock¡¡does¡¡not¡¡hinder¡¡or¡¡stop¡¡¡¡
deadlocks£»¡¡which¡¡can¡¡occur¡¡if¡¡you¡¡are¡¡not¡¡careful¡¡with¡¡how¡¡you¡¡write¡¡your¡¡code¡£¡¡The¡¡reader/¡¡
writer¡¡lock¡¡is¡¡concerned¡¡about¡¡only¡¡the¡¡code¡¡that¡¡is¡¡used¡¡to¡¡manage¡¡data¡£¡¡
Implementing¡¡a¡¡Producer/Consumer¡¡Architecture¡¡
The¡¡producer/consumer¡¡technique¡¡has¡¡never¡¡been¡¡defined¡¡as¡¡a¡¡type£»¡¡but¡¡it¡¡is¡¡used¡¡throughout¡¡¡¡
many¡¡multithreaded¡¡applications¡£¡¡The¡¡idea¡¡behind¡¡a¡¡producer/consumer¡¡architecture¡¡is¡¡to¡¡¡¡
split¡¡the¡¡problem¡¡into¡¡two¡¡parts¡£¡¡One¡¡side¡¡is¡¡the¡¡producer¡¡of¡¡data£»¡¡information£»¡¡and¡¡tasks¡£¡¡The¡¡¡¡
producer¡¡wraps¡¡up¡¡the¡¡information¡¡into¡¡a¡¡task¡¡to¡¡be¡¡executed¡£¡¡The¡¡other¡¡side¡¡is¡¡the¡¡consumer£»¡¡¡¡
and¡¡it¡¡is¡¡responsible¡¡for¡¡unwrapping¡¡the¡¡information¡¡and¡¡doing¡¡something¡¡with¡¡it¡£¡¡
Using¡¡a¡¡Hidden¡¡Producer/Consumer¡¡Implementation¡¡
In¡¡Windows¡¡GUIs£»¡¡multithreaded¡¡applications¡¡are¡¡not¡¡allowed¡¡to¡¡access¡¡UI¡¡ponents¡¡if¡¡they¡¡¡¡
are¡¡not¡¡the¡¡thread¡¡that¡¡created¡¡the¡¡UI¡¡element¡£¡¡To¡¡get¡¡around¡¡that¡¡problem£»¡¡the¡¡Windows¡£Forms¡¡¡¡
library¡¡uses¡¡the¡¡Invoke£¨£©¡¡method¡£¡¡To¡¡demonstrate£»¡¡we¡¯ll¡¡create¡¡a¡¡GUI¡¡application¡¡that¡¡uses¡¡another¡¡¡¡
thread¡¡to¡¡periodically¡¡increment¡¡a¡¡counter¡¡that¡¡is¡¡displayed¡¡in¡¡a¡¡text¡¡box¡£¡¡
¡¡¡¡¡¡¡¡¡¡Follow¡¡these¡¡steps£º¡¡¡¡
¡¡¡¡¡¡¡¡¡¡1¡£¡¡¡¡Create¡¡a¡¡new¡¡Windows¡¡Forms¡¡application£»¡¡and¡¡set¡¡it¡¡as¡¡the¡¡startup¡¡project¡¡if¡¡it¡¡isn¡¯t¡¡already¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡£¨right¡click¡¡its¡¡name¡¡and¡¡select¡¡Set¡¡as¡¡StartUp¡¡Project£©¡£¡¡
¡¡¡¡¡¡¡¡¡¡2¡£¡¡¡¡Drag¡¡a¡¡TextBox¡¡control¡¡onto¡¡Form1¡¡in¡¡the¡¡design¡¡window¡£¡¡
¡¡¡¡¡¡¡¡¡¡3¡£¡¡¡¡Select¡¡the¡¡TextBox¡¡control¡£¡¡If¡¡the¡¡Properties¡¡window¡¡isn¡¯t¡¡visible£»¡¡right¡click¡¡the¡¡control¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡and¡¡select¡¡Properties¡£¡¡
¡¡¡¡¡¡¡¡¡¡4¡£¡¡¡¡Change¡¡the¡¡TextBox¡¯s¡¡Name¡¡property¡¡to¡¡txtMessage¡£¡¡
¡¡¡¡¡¡¡¡¡¡5¡£¡¡¡¡Right¡click¡¡the¡¡form¡¡and¡¡select¡¡View¡¡Code¡£¡¡
¡¡¡¡¡¡¡¡¡¡6¡£¡¡¡¡Add¡¡the¡¡following¡¡code¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Imports¡¡System¡£Threading¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Public¡¡Class¡¡Form1¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Private¡¡_counter¡¡As¡¡Integer¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Private¡¡Sub¡¡IncrementCounter£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Me¡£txtMessage¡£Text¡¡=¡¡¡¨Counter¡¡£¨¡¨¡¡&¡¡_counter¡¡&¡¡¡¨£©¡¨¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡_counter¡¡£«=¡¡1¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡