读写锁是针对于读写操作的互斥锁。

基本遵循两大原则:

1、可以随便读。多个goroutin同时读。

2、写的时候,啥都不能干。不能读,也不能写。

解释:

在32位的操作系统中,针对int64类型值的读操作和写操作不可能只由一个CPU指令完成。如果一个写的操作刚执行完了第一个指令,时间片换给另一个读的协程,这就会读到一个错误的数据。

RWMutex提供四个方法:

func (*RWMutex) Lock //写锁定

func (*RWMutex) Unlock //写解锁

func (*RWMutex) RLock //读锁定

func (*RWMutex) RUnlock //读解锁

代码实例:

1、可以随便读:

package main

import (

"sync"

"time"

)

var m *sync.RWMutex

func main() {

m = new(sync.RWMutex)

//可以多个同时读

go read()

go read()

time.Sleep( * time.Second)

}

func read(i int) {

println(i, "read start")

m.RLock()

println(i, "reading")

time.Sleep( * time.Second)

m.RUnlock()

println(i, "read end")

}

运行结果:

1 read start

1 reading

2 read start

2 reading

1 read end

2 read end

可以看到1读还没结束(倒数第二行)的时候,2已经在读(倒数第三行)了。

2、写的时候啥也不能干:

package main

import (

"sync"

"time"

)

var m *sync.RWMutex

func main() {

m = new(sync.RWMutex)

//写的时候啥都不能干

go write()

go read()

go write()

time.Sleep( * time.Second)

}

func read(i int) {

println(i, "read start")

m.RLock()

println(i, "reading")

time.Sleep( * time.Second)

m.RUnlock()

println(i, "read end")

}

func write(i int) {

println(i, "write start")

m.Lock()

println(i, "writing")

time.Sleep( * time.Second)

m.Unlock()

println(i, "write end")

}

输出:

1 write start

1 writing

2 read start

3 write start

1 write end

2 reading

2 read end

3 writing

3 write end

可以看到:

1、1 write end结束之后,2才能reading

2、2 read end结束之后,3 才能writing

go中的读写锁RWMutex的更多相关文章

  1. Golang 读写锁RWMutex 互斥锁Mutex 源码详解

    前言 Golang中有两种类型的锁,Mutex (互斥锁)和RWMutex(读写锁)对于这两种锁的使用这里就不多说了,本文主要侧重于从源码的角度分析这两种锁的具体实现. 引子问题 我一般喜欢带着问题去 ...

  2. Go基础系列:互斥锁Mutex和读写锁RWMutex用法详述

    sync.Mutex Go中使用sync.Mutex类型实现mutex(排他锁.互斥锁).在源代码的sync/mutex.go文件中,有如下定义: // A Mutex is a mutual exc ...

  3. java多线程:并发包中ReentrantReadWriteLock读写锁的原理

    一:读写锁解决的场景问题--->数据的读取频率远远大于写的频率的场景,就可以使用读写锁.二:读写锁的结构--->用state一个变量.将其转化成二进制,前16位为高位,标记读线程获取锁的次 ...

  4. java中ReentrantReadWriteLock读写锁的使用

    Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. 读写锁:分为读 ...

  5. Java 并发包中的读写锁及其实现分析

    1. 前言 在Java并发包中常用的锁(如:ReentrantLock),基本上都是排他锁,这些锁在同一时刻只允许一个线程进行访问,而读写锁在同一时 刻可以允许多个读线程访问,但是在写线程访问时,所有 ...

  6. Java中的读写锁

    一.读写锁 1.初识读写锁 a)Java中的锁——Lock和synchronized中介绍的ReentrantLock和synchronized基本上都是排它锁,意味着这些锁在同一时刻只允许一个线程进 ...

  7. MongoDB中的读写锁

    1. MongoDB 使用的锁 MongoDB 使用的是“readers-writer”锁, 可以支持并发但有很大的局限性当一个读锁存在,许多读操作可以使用这把锁,然而, 当一个写锁的存在,一个单一的 ...

  8. 线程中的读写锁ReadWriteLock

    Lock锁还有两个非常强大的类 ReadWriteLock接口实现类ReentrantReadWriteLock(非常重要的锁) 想实现 读取的时候允许多线程并发访问,写入的时候不允许. 这种效果.. ...

  9. java中的读/写锁

    读写锁接口:ReadWriteLock,它的具体实现类为:ReentrantReadWriteLock 使用场景: 对于一个资源,读读能共存,读写不能共存,写写不能共存. 锁降级:从写锁变成读锁: 锁 ...

随机推荐

  1. 6M - 循环多少次?

    我们知道,在编程中,我们时常需要考虑到时间复杂度,特别是对于循环的部分.例如, 如果代码中出现 for(i=1;i<=n;i++) OP ; 那么做了n次OP运算,如果代码中出现 fori=1; ...

  2. javaweb开发.常用的第三方包

      序号 开发包名称 描述 1 dom4j-1.6.1.jar dom4j用于操作XML文件 2 jaxen-1.1-beta-6.jar 用于解析XPath表达式 3 commons-beanuti ...

  3. 设计模式 策略模式2 c++11

    根据需求的不同 选择不同的策略算法 之前是保存的各种策略类的指针 这里直接使用 function  bind 选择对应的算法 代码 // 005.cpp: 定义控制台应用程序的入口点. // #inc ...

  4. Sort Array By Parity II LT922

    Given an array A of non-negative integers, half of the integers in A are odd, and half of the intege ...

  5. activeMq-3 Spring整合activeMq

    与jdbcTemplate相似的是,Spring也提供了JmsTemplate 生产者使用JmsTemplate生产消息,消费者实现一个监听器用于获取消息 项目用maven构建,jdk1.8, 文末提 ...

  6. PHP-循环结构-数组(难)

    今日目标: (1)循环结构 —— do..while.. —— 掌握 (2)循环结构 —— for —— 重点 (3)数组 —— 重点 1.PHP中的循环结构 —— do..while... do: ...

  7. 网站日志流量分析采集(LuaJIT系统环境部署-node03,相关jar包自己手动上传)

    注:/usr/local/src 是源码包路径,可以自己更改 服务器中安装依赖 yum -y install gcc perl pcre-devel openssl openssl-devel 上传 ...

  8. sqoop加载mysql数据库

    ./bin/sqoop list-databases --connect jdbc:mysql://node-001:3306/ --username root --password hadoop

  9. 可遇不可求的Question之flash的socket连接安全策略文件篇

    flash的socket连接安全策略文件   最近公司做压力测试的时候,发现了一个问题.flash的socket客户端向服务端请求安全策略文件的时候,服务端负责回发策略文件的端口能连接上,但是没有响应 ...

  10. 配置docker官方源并用yum安装docker

    一.docker的官方安装文档: https://docs.docker.com/engine/installation/linux/centos/ 由docker给的文档可以看出它也只是去配置了一个 ...