首页 > 其他 > 详细

ConcurrentHashMap

时间:2019-10-26 10:31:44      阅读:90      评论:0      收藏:0      [点我收藏+]

下图是Java里的概念,其中 Hashtable 和 SynchronizedMap 都是对整个map加锁,所以多个thread没法同时修改。

ConcurrentHashMap 则允许多个thread同时访问不同的entry,即如果thread操作的key不同,这些thread是可以同时读写的。如果多个thread访问同一个key,这里就类似reader-writer lock。

技术分享图片

用Seperate Chaining来实现hashmap,并对每个entry都设置一个reader-writer lock,即C++17里的shared_mutex。

注意vector容器如果调用resize或者别的需要copy的函数,会报错,因为mutex不是moveable的。

https://stackoverflow.com/questions/16465633/how-can-i-use-something-like-stdvectorstdmutex

#include "bits/stdc++.h"
using namespace std;

struct HashNode {
    int key;
    int value;
    HashNode(int k, int v):key(k),value(v){}
};

class HashMap {
    vector<list<HashNode>> v;
    vector<shared_mutex > mtxs;
    int capacity;
public:
    HashMap(int cap){
        capacity = cap;
        v.resize(capacity);
        vector<shared_mutex> tmp(capacity);
        mtxs.swap(tmp);
    }
    int hashFunction(int key){
        return key%capacity;
    }
    void insert(int key, int value){
        int hashIndex=hashFunction(key);
        unique_lock<shared_mutex> writeLock(mtxs[hashIndex]);
        auto &cur_list=v[hashIndex];
        for (auto it=cur_list.begin();it!=cur_list.end();++it){
            if (it->key==key){
                it->value=value;
                return;
            }
        }
        cur_list.emplace_back(key,value);
    }
    void erase(int key){
        int hashIndex=hashFunction(key);
        unique_lock<shared_mutex> writeLock(mtxs[hashIndex]);
        auto &cur_list=v[hashIndex];
        for (auto it=cur_list.begin();it!=cur_list.end();++it){
            if (it->key==key){
                cur_list.erase(it);
                return;
            }
        }
    }
    int at(int key){
        int hashIndex=hashFunction(key);
        shared_lock<shared_mutex> readLock(mtxs[hashIndex]);
        auto &cur_list=v[hashIndex];
        for (auto it=cur_list.begin();it!=cur_list.end();++it){
            if (it->key==key){
                return it->value;
            }
        }
        return INT_MIN; // not found
    }
    void display(){
        for (int i=0;i<capacity;++i){
            cout << i << ": ";
            for (auto x:v[i]) cout<<x.key<< ;
            cout << endl;
        }
    }
};

int main() {
    HashMap hashmap(7);
    vector<int> to_insert{15,11,27,8};
    for (int x:to_insert) hashmap.insert(x,x);
    hashmap.display();
    cout<<hashmap.at(8);
    hashmap.erase(8);
    hashmap.display();
    cout<<hashmap.at(8);
    return 0;
}

 

Reference

https://codepumpkin.com/hashtable-vs-synchronizedmap-vs-concurrenthashmap/

https://stackoverflow.com/questions/16465633/how-can-i-use-something-like-stdvectorstdmutex

ConcurrentHashMap

原文:https://www.cnblogs.com/hankunyan/p/11741696.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!