• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Go并发编程之美-读写锁

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

一、前言

go语言类似Java JUC包也提供了一些列用于多线程之间进行同步的措施,比如低级的同步措施有 锁、CAS、原子变量操作类。相比Java来说go提供了独特的基于通道的同步措施。本节我们先来看看go中读写锁

二、读写锁

go中读写锁,在没有线程获取写锁情况下多个线程可以同时获取读锁,读锁是可重入锁,写锁则是互斥锁(不可重入)。

package main

import (
    "fmt"
    "sync"
    "time"
)

var (
    counter int            //计数器
    wg      sync.WaitGroup //信号量
    lock    sync.RWMutex   //读写锁
)

func main() {

    //1.两个信号
    wg.Add(1)

    //2.获取读锁
    fmt.Println("main thread wait rlock")
    lock.RLock()
    fmt.Println("main thread got rlock")
    //3.开启子线程
    go incCounter()
    fmt.Println(counter)
    time.Sleep(time.Second * 5)
    //4.释放读锁
    lock.RUnlock()
    fmt.Println("main thread release rlock")

    //5.等待子线程结束
    wg.Wait()
    fmt.Println(counter)

}

func incCounter() {
    defer wg.Done()

    //2.1.获取锁
    fmt.Println("sub thread wait rlock")
    lock.Lock()
    fmt.Println("sub thread got rlock")

    //2.2.计数加1
    counter++

    //2.3.释放独占锁
    lock.Unlock()
    fmt.Println("sub thread relese rlock")

}
  • 如上代码go中使用sync.RWMutex可以获取一个开箱即用的读写锁
  • 代码(2)主线程使用lock.RLock()获取读锁,然后开启了子线程(代码3),然后在主线程持有读锁的情况下休眠了5s后释放了锁。
  • 子线程在代码2.1尝试使用 lock.Lock()获取写锁,由于主线程还没释放读锁,所以子线程阻塞到了这里,直到主线程休眠后执行代码4释放了读锁。
  • 执行代码会输出:
main thread wait rlock
main thread got rlock
0
sub thread wait rlock
main thread release rlock
sub thread got rlock
sub thread relese rlock
1

这个例子说明了,当有线程获取了读锁并没释放时候,获取写锁的线程要等待。

另外使用下面方法可以验证读锁是可重入锁:

    lock.RLock()
    lock.RLock()
    fmt.Println(counter)
    lock.RUnlock()
    lock.RUnlock()

使用下面代码可以验证同一个线程的读锁,不能晋升为写锁:

    lock.RLock()
    lock.Lock()
    fmt.Println(counter)
    lock.Unlock()
    lock.RUnlock()

上面代码执行会报错:

三、总结

go中读写锁中的读锁是可重入共享锁,写锁是互斥锁,读锁不能晋升为写锁。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go,redis实现订阅和发布发布时间:2022-07-10
下一篇:
window.history.go(-1) 无效,不回退页面发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap