go实现并发安全hashtable 拉链法
在这个实现中,HashTable包含多个bucket,每个bucket都有一个互斥锁来保证并发安全。Put方法用于插入键值对,Get方法用于获取值,Delete方法用于删除键值对。通过哈希函数确定键应该存储在哪个bucket中,然后在对应的bucket中进行操作。这种实现方式可以有效地处理并发访问,确保哈希表在多线程环境下的正确性。
package main
import (
"sync"
)
type HashTable struct {
buckets []*bucket
bucketSize int
}
type bucket struct {
mu sync.Mutex
items map[string]interface{}
}
func NewHashTable(bucketSize int) *HashTable {
buckets := make([]*bucket, bucketSize)
for i := range buckets {
buckets[i] = &bucket{
items: make(map[string]interface{}),
}
}
return &HashTable{
buckets: buckets,
bucketSize: bucketSize,
}
}
func (ht *HashTable) hash(key string) int {
hashValue := 0
for _, char := range key {
hashValue += int(char)
}
return hashValue % ht.bucketSize
}
func (ht *HashTable) Put(key string, value interface{}) {
bucketIndex := ht.hash(key)
bucket := ht.buckets[bucketIndex]
bucket.mu.Lock()
bucket.items[key] = value
bucket.mu.Unlock()
}
func (ht *HashTable) Get(key string) (interface{}, bool) {
bucketIndex := ht.hash(key)
bucket := ht.buckets[bucketIndex]
bucket.mu.Lock()
value, ok := bucket.items[key]
bucket.mu.Unlock()
return value, ok
}
func (ht *HashTable) Delete(key string) {
bucketIndex := ht.hash(key)
bucket := ht.buckets[bucketIndex]
bucket.mu.Lock()
delete(bucket.items, key)
bucket.mu.Unlock()
}
func main() {
ht := NewHashTable(10)
// 并发安全地插入数据
var wg sync.WaitGroup
for i := 0; i < 100; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
ht.Put(fmt.Sprintf("key%d", i), i)
}(i)
}
wg.Wait()
// 并发安全地读取数据
for i := 0; i < 100; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
value, ok := ht.Get(fmt.Sprintf("key%d", i))
if ok {
fmt.Println(value)
}
}(i)
}
wg.Wait()
// 并发安全地删除数据
for i := 0; i < 100; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
ht.Delete(fmt.Sprintf("key%d", i))
}(i)
}
wg.Wait()
}