美文网首页
细粒度锁的实现

细粒度锁的实现

作者: 黑蚁blackant | 来源:发表于2018-07-10 15:59 被阅读0次

单个的读写锁性能太差,
分段锁设计该粗暴,下面是细粒度锁的实现,很巧妙,值得琢磨。


type semaphore struct {
    // Number of Acquires - Releases. When this goes to zero, this structure is removed from map.
    // Only updated inside blockingKeyCountLimit.lk lock.
    refs int

    max   int
    value int
    wait  sync.Cond
}

func newSemaphore(max int) *semaphore {
    return &semaphore{
        max:  max,
        wait: sync.Cond{L: new(sync.Mutex)},
    }
}

func (s *semaphore) Running() int {
    s.wait.L.Lock()
    defer s.wait.L.Unlock()

    return int(s.value)
}

func (s *semaphore) Acquire() {
    s.wait.L.Lock()
    defer s.wait.L.Unlock()
    for {
        if s.value+1 <= s.max {
            s.value++
            return
        }
        s.wait.Wait()
    }
    panic("Unexpected branch")
}

func (s *semaphore) Release() {
    s.wait.L.Lock()
    defer s.wait.L.Unlock()
    s.value--
    if s.value < 0 {
        panic("semaphore Release without Acquire")
    }
    s.wait.Signal()
}

type blockingKeyCountLimit struct {
    mutex   sync.RWMutex
    current map[string]*semaphore
    limit   int
}

func NewBlockingKeyCountLimit(n int) limit.Limit {
    return &blockingKeyCountLimit{current: make(map[string]*semaphore), limit: n}
}

func (l *blockingKeyCountLimit) Running() int {
    l.mutex.RLock()
    defer l.mutex.RUnlock()

    all := 0
    for _, v := range l.current {
        all += v.Running()
    }
    return all
}

func (l *blockingKeyCountLimit) Acquire(key2 []byte) error {
    key := string(key2)

    l.mutex.Lock()
    kl, ok := l.current[key]
    if !ok {
        kl = newSemaphore(l.limit)
        l.current[key] = kl

    }
    kl.refs++
    l.mutex.Unlock()

    kl.Acquire()

    return nil
}

func (l *blockingKeyCountLimit) Release(key2 []byte) {
    key := string(key2)

    l.mutex.Lock()
    kl, ok := l.current[key]
    if !ok {
        panic("key not in map. Possible reason: Release without Acquire.")
    }
    kl.refs--
    if kl.refs < 0 {
        panic("internal error: refs < 0")
    }
    if kl.refs == 0 {
        delete(l.current, key)
    }
    l.mutex.Unlock()

    kl.Release()
}

相关文章

  • 细粒度锁的实现

    单个的读写锁性能太差,分段锁设计该粗暴,下面是细粒度锁的实现,很巧妙,值得琢磨。

  • Guava library 中的 Striped Locks

    Striped Locks用于实现在更细粒度的锁控制和性能之间平衡。Guava是Google提供的Java开发工具...

  • 并发场景下死锁

    案例场景 例如账户A 转账户B、账户C 转账户D这两个转账操作。 这种方式采用了细粒度锁。使用细粒度锁可以提高并行...

  • Java 中常见的细粒度锁实现

    上篇文章大致说了下 ReentrantLock 类的使用,对 ReentrantLock 类有了初步的认识之后让我...

  • RWMutex —— 细粒度的读写锁

    RWMutex —— 细粒度的读写锁 我们之前有讲过 Mutex 互斥锁[https://github.com/M...

  • Java 细粒度锁续篇

    在上篇文章中大概介绍了 Java 中细粒度锁的几种实现方式,并且针对每种方式都做了优缺点说明,在使用的时候就需要根...

  • 解析InnoDB锁类型及使用方式

    为了提高InnoDB存储引擎的并发性,InnoDB采用了细粒度的行锁,并在针对不同的锁使用不同级别锁或不使用锁。本...

  • 锁和synchronized

    锁的常见概念 互斥: 同一时刻只有一个线程执行 临界区:一段需要互斥执行的代码 细粒度锁: 用不同的锁对受保护资源...

  • 技术翻译常用短语

    implement fine-grained scroll behavior control. 实现细粒度的滚动行为控制

  • ComponentCallbacks2接口简介

    ComponentCallbacks2接口扩展自ComponentCallbacks回调接口,用以实现更细粒度的内...

网友评论

      本文标题:细粒度锁的实现

      本文链接:https://www.haomeiwen.com/subject/ghxqpftx.html