首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go并发编程之美-读写锁

Go并发编程之美-读写锁

原创
作者头像
加多
发布2019-02-15 19:24:57
5600
发布2019-02-15 19:24:57
举报
文章被收录于专栏:Java编程技术Java编程技术

一、前言

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可以获取一个开箱即用的读写锁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这个例子说明了,当有线程获取了读锁并没释放时候,获取写锁的线程要等待。
  • 代码(2)主线程使用lock.RLock()获取读锁,然后开启了子线程(代码3),然后在主线程持有读锁的情况下休眠了5s后释放了锁。
  • 子线程在代码2.1尝试使用 lock.Lock()获取写锁,由于主线程还没释放读锁,所以子线程阻塞到了这里,直到主线程休眠后执行代码4释放了读锁。
  • 执行代码会输出:

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

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

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

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

上面代码执行会报错:

image.png
image.png

三、总结

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、读写锁
  • 三、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档