資源描述:
《ConcurrentDictionary實(shí)現(xiàn)》由會員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫。
1、ConcurrentDictionary實(shí)現(xiàn).Net4增加的System.Collection.Concurrent線程安全的集合實(shí)現(xiàn),這兒有MS的性能測試報(bào)告:Thread-safeCollectionsin.NETFramework4andTheirPerformanceCharacteristics??偟膩碚f效率還是很不錯的,為了提高效率用了一些技巧,接口上也多是TryXXX。????????ConcurrentDictionary采用Level-Lock方式,和Dictionary一樣還是只有一個buckets,只是內(nèi)部l
2、ock時,采用locknum=key.GetHashcode%lockCount,lock(objects[num]),方式,默認(rèn)情況下DefaultConcurrencyLevel=4*Environment.ProcessorCount;?也就是4*CPU核心數(shù)。相比于一個lockobject,在高并發(fā)使用多個lockobject可以很大減少lock等待的可能;但在整個集合操作(如:Count,Clear,Expend..)還是需要全部加鎖后操作。????????為啥接口都變成TryXXX呢:因?yàn)槿鏏dd和Remove之間存在
3、競爭,不能再像單線程集合那樣簡單的拋出異常,不能拋出異常那就得要一個是否操作成功的返回碼~?下面是節(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu),算法也有很大的區(qū)別,這里使用類,hashtable,Dictionary都用的是struct。問題在于如果使用HashTable雙hash算法,對同一個數(shù)組就沒法做Level啦。Dictionary分別兩個數(shù)組Bluckets和Entitys,同樣無法區(qū)分level。至于hash算法比起前兩者都要簡單不少呢。所以采用了class可以使用m_next連接方式解決沖突,m_ext使用volatile可解決多線程緩存同步問題。
4、來咱來計(jì)算一下內(nèi)存占用問題吧使用class方式無疑對于簡單字段要占用多不少內(nèi)存,就拿int-int來算:?Dictionary4*5=20字節(jié)/nodeConcurrentDictionary在x64下:8+4+4+4+8+8+8=42字節(jié)/node要多占不少內(nèi)存那。不過對于Node=null時,空位多的時候也能節(jié)省部分內(nèi)存,不過一般空位多了不應(yīng)該~------?blucket(8)+Node(key(4)+value(4)+hash(4)+next(8)+methodRef(8))+syncblk(8))*有個想法咱吧Dicti
5、onary改造一下位LevelLock,用多個Dict,前面文章有測試效果,還不錯。1:privateclassNode//不再是struck了呢2:{3:internalTKeym_key;4:internalTValuem_value;5:internalvolatileNodem_next;//在這兒volatile很重要6:internalintm_hashcode;7:internalnode()8:{9:this.m_key=key;10:this.m_value=value;11:this.m_next=next;1
6、2:this.m_hashcode=hashcode;13:}14:}??下面是Add的實(shí)現(xiàn):1:privateboolTryAddInternal(TKeykey,TValuevalue,boolupdateIfExists,boolacquireLock,outTValueresultingValue)2:{3:inthashCode=this.m_comparer.GetHashCode(key);4:checked5:{6:ConcurrentDictionary.Node[]buckets;7:
7、boolflag;8:while(true)9:{10:buckets=this.m_buckets;11:intnum;12:intnum2;13:this.GetBucketAndLockNo(hashCode,outnum,outnum2,buckets.Length);//計(jì)算Hash地址和新的節(jié)點(diǎn)落在那個Lock上面14:flag=false;15:boolflag2=false;16:try17:{18:if(acquireLock)19:{20:Monitor.Enter(this.m_locks[num2],ref
8、flag2);21:}22:if(buckets!=this.m_buckets)23:{24:continue;//這兒很重要Enter之前如果不做這個判斷,可能因?yàn)樽侄螖U(kuò)容而丟失值25:}26:ConcurrentDictionary