本篇文章我们用Go封装一个无等待锁库。文章参考自:https://github.com/brewlin/net-protocol

1.锁的封装

type Mutex struct {
v int32
ch chan struct{}
}

2.锁的初始化

func (m *Mutex) Init() {
m.v = 1
m.ch = make(chan struct{}, 1)
}

3.等待锁

如果没有拿到锁值,将会阻塞在信道上。

func (m *Mutex) Lock() {
if atomic.AddInt32(&m.v, -1) == 0 {
return
} for {
if v := atomic.LoadInt32(&m.v); v >= 0 && atomic.SwapInt32(&m.v, -1) == 1 {
return
} <-m.ch
}
}

4.无等待锁

如果没有拿到锁值,会直接返回。

func (m *Mutex) TryLock() bool {
v := atomic.LoadInt32(&m.v)
if v <= 0 {
return false
}
return atomic.CompareAndSwapInt32(&m.v, 1, 0)
}

5.释放锁

释放锁时,向信道发送值以唤醒阻塞的协程。

func (m *Mutex) Unlock() {
if atomic.SwapInt32(&m.v, 1) == 0 {
return
} select {
case m.ch <- struct{}{}:
default:
}
}

6.使用示例

通过对上锁时机的控制,我们让GetCount()直接返回了-1,实现了无等待锁。

var (
count int
countGuard *Mutex
) func GetCount() int {
if countGuard.TryLock() {
countGuard.Unlock()
return count
} else {
return -1
}
} func SetCount(c int) {
countGuard.Lock()
time.Sleep(time.Second * 2)
count = c
countGuard.Unlock()
} func main() {
countGuard = new(Mutex)
countGuard.Init() go SetCount(1)
time.Sleep(time.Second)
fmt.Println(GetCount())
}

Go组件库总结之无等待锁的更多相关文章

  1. java高并发程序设计模式-并发级别:阻塞、无障碍、无锁、无等待【转载】

    一般认为并发可以分为阻塞与非阻塞,对于非阻塞可以进一步细分为无障碍.无锁.无等待,下面就对这几个并发级别,作一些简单的介绍. 1.阻塞 阻塞是指一个线程进入临界区后,其它线程就必须在临界区外等待,待进 ...

  2. 如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源

    1.前言 关于微信内部正在使用的网络层封装库Mars开源的消息,1个多月前就已满天飞(参见<微信Mars:微信内部正在使用的网络层封装库,即将开源>),不过微信团队没有失约,微信Mars ...

  3. HslCommunication组件库使用说明

    一个由个人开发的组件库,携带了一些众多的功能,包含了数据网络通信,文件上传下载,日志组件,PLC访问类,还有一些其他的基础类库. nuget地址:https://www.nuget.org/packa ...

  4. 【转】如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源

    网上看到关于微信官方的跨平台跨业务的终端基础组件Mars的介绍文章,转载这这里.源代码: https://github.com/Tencent/mars作者:男人链接:https://zhuanlan ...

  5. Java HTTP 组件库选型看这篇就够了

    最近项目需要使用 Java 重度调用 HTTP API 接口,于是想着封装一个团队公用的 HTTP client lib. 这个库需要支持以下特性: 连接池管理,包括连接创建和超时.空闲连接数控制.每 ...

  6. 免费开源的 .NET 分布式组件库 Exceptionless Foundatio

    前言 在互联网时代,分布式应用.系统变得越来越多,我们在使用 .Net 技术构建分布式系统的时候,需要使用到一些组件或者是助手库来帮助我们提高生产力以及应用程序解耦,但是纵观.Net圈,能够符合要求的 ...

  7. HslCommunication组件库使用说明 (转载)

    一个由个人开发的组件库,携带了一些众多的功能,包含了数据网络通信,文件上传下载,日志组件,PLC访问类,还有一些其他的基础类库. nuget地址:https://www.nuget.org/packa ...

  8. beeshell —— 开源的 React Native 组件库

    介绍 beeshell 是一个 React Native 应用的基础组件库,基于 0.53.3 版本,提供一整套开箱即用的高质量组件,包含 JavaScript(以下简称 JS)组件和复合组件(包含 ...

  9. 使用自定义验证组件库扩展 Windows 窗体

    使用自定义验证组件库扩展 Windows 窗体             1(共 1)对本文的评价是有帮助 - 评价此主题                          发布日期 : 8/24/20 ...

  10. 用JAVA实现无等待数据库连接池

    我们都知道数据库连接是一种有限和非常昂贵的应用资源,怎样对这些资源进行高效的管理,能有效的改善整个系统的性能和健壮性.数据库连接池正是针对这个问题而提出来的. 数据库连接负责分配.释放和管理数据库连接 ...

随机推荐

  1. 制作 2D 素材|基于 AI 5 天创建一个农场游戏,第 4 天

    欢迎使用 AI 进行游戏开发! 在本系列中,我们将使用 AI 工具在 5 天内创建一个功能完备的农场游戏.到本系列结束时,您将了解到如何将多种 AI 工具整合到游戏开发流程中.本系列文章将向您展示如何 ...

  2. 【CodeSmith】The System.Data.SQLite library is not installed on this computer,不能使用SQLite解决办法

    1.出现问题原因 1)System.Data.SQLite 尚未安装在您的计算机上 2)System.Data.SQLite 尚未正确配置 2.下载并安装System.Data.Sqlite [注意] ...

  3. 学习Java Day 5

    今天看视频学习了一下eclipse的使用方法,解决了昨天运行不了的结果,并尝试了一下java的输入:

  4. LinkedList内部实现原理

    LinkedList内部实现原理 java list 同ArrayList内部原理一样 我们先创建一个LinkedList对象LinkedList<String> li = new Lin ...

  5. 题解 [ZJOI2007]棋盘制作

    把悬线法这个坑填了,还是很简单的 qwq. 悬线法一般解决有一定约束条件的最大矩形问题.悬线的定义是从一个点一直往上走直到边界或者不符合条件结束. 炒个例子,在这题里面比如说有这样一个矩形 0 1 0 ...

  6. git拉取新分支、删除分支、修改远程分支

    1.拉取新分支 git checkout master           切换到master分支 git pull                                   更新到最新代码 ...

  7. LRU 居然翻译成最近最少使用?真相原来是这样!(附力扣题解)

    前言 相信有很多同学和我一样,第一次碰到 LRU(Least Recently Used) 的这个解释「最近最少使用」都不知道是什么意思,用汤家凤老师的话来说: 我真的感到匪夷所思啊! 最近是表示时间 ...

  8. KingbaseES R6集群误删除备节点的集群目录恢复方式

    一.场景 一主一备环境 主节点:192.168.17.9 备节点:192.168.17.10 故障:备节点安装目录/home/kingbase/cluster备删除 二.恢复方式 1.备节点集群目录备 ...

  9. linux上安装python3(yum方式)

    可联通外网的linux系统终端上安装python3 1,建立yum仓库: https://mirrors.163.com/centos/7.9.2009/os/x86_64/ 2,使用yum下载安装对 ...

  10. Dockerfile构建python项目

    一.步骤 1.镜像基础 2.复制代码 3.设置工作目录 4.把需要执行的shell命令编写成脚本文件 5.配置容器启动自动执行脚本,CMD在docker run时运行脚本 DockerFile 脚本 ...