golang团队在sync中提供了很多的原子操作函数,将原子操作转向由单独一个包提供,而不是像Java那样提供各种累,确实上手得更加简单。但是golang原生提供的并发操作没有Java来得丰富,或者庞大(这里并不想展开语言相杀),只是笔者在练习的时候,想试着用golang实现类似Java中的valatile的语义功能,却发现golang没有提供类似的关键字,这个时候只能借助sync和sync/atmoic的同步语句来实现对应的功能。事实是,如果是借助锁的同步方式来实现对应的valatile语义,笔者认为大大浪费和误会了golang的设计协程的初衷,此时笔者想起了golang团队的一句话

勿以共享方式通信,以通信实现共享

    为什么不试试用下通道,看看能不能达到类似的功能。valatile修饰的变量本身则是个共享变量,因此,我们的目标是用通信的方式实现对共享变量的修改。下面笔者以自定义session管理器作为例子展开说明。

StandardSession有个isValidChan属性,类型是一个chan bool,标志该session是否有效,但是同一时刻可能会有多个客户端对该session进行无效化操作,即isValidChan属性符合valatile的应用场景。

type StandardSession struct {

    isValidChan         chan bool
}

    我们需要对isValidChan属性初始化为容量为1的通道,即make(chan bool, 1);isValidChan <- true,注意容易必须设置为1,而且必须发送默认值到通道中。接下来则是设计对该共享变量的读取和设置,以模仿volatila的语义

    这里需要说明两点知识点,一是容量为0的通道,通信是同步且无缓冲的:在有接受者接收数据之前,发送不会结束。可以想象一个无缓冲的通道在没有空间来保存数据的时候:必须要一个接收者准备好接收通道的数据然后发送者可以直接把数据发送给接收者。所以通道的发送/接收操作在对方准备好之前是阻塞的,二是,如果容量大于 0,通道就是异步的了:缓冲满载(发送)或变空(接收)之前通信不会阻塞,元素会按照发送的顺序被接收。如果容量是0或者未设置,通信仅在收发双方准备好的情况下才可以成功。以下的两个则是利用了这两个特点,设置通道的容量为1,当有一条协程接受该通道的值之后,通道的长度变为0,其他协程必须得阻塞等待该协程重新发送新的值到该通道之后,才能读取最新的值,即共享的值保存在通道中,同一时刻只有一条协程能够对该通道进行操作

//实现对IsValid原子修改
func (session *StandardSession) SetIsValid(isValid bool) {
    <-session.isValidChan
    session.isValidChan <- isValid
}

//实现对IsValid原子读取
func (session *StandardSession) IsValid() bool {
    b := <-session.isValidChan
    session.isValidChan <- b
    return b
}

    这里本质上还是同步化以达到共享变量的即时更新,volatile的原理是不需要通过同步指令,针对CPU指令级别的,是通过强制更新处理器内存,刷新CPU缓存以达到即时更新。所以这里只能说是笔者作为练习的模仿实现,如若读者有更好的实现,不吝赐教。

简书地址:https://www.jianshu.com/p/4a4feb2c5590

golang使用通道模仿实现valatile语义的更多相关文章

  1. 【转】Golang 关于通道 Chan 详解

    原文:http://blog.csdn.net/netdxy/article/details/54564436 在用 chan 类型时,发生死锁的错误,表面上看不出什么问题 ------------- ...

  2. [Go] golang缓冲通道实现资源池

    go的pool资源池:1.当有多个并发请求的时候,比如需要查询数据库2.先创建一个2个容量的数据库连接资源池3.当一个请求过来的时候,去资源池里请求连接资源,肯定是空的就创建一个连接,执行查询,结束后 ...

  3. [Go] golang缓冲通道实现管理一组goroutine工作

    通道1.当一个资源需要在goroutine之间共享时,通道在goroutine之间架起了一个管道2.无缓冲通道和有缓冲通道,make的第二个参数就是缓冲区大小3.无缓冲通道需要发送和接收都准备好,否则 ...

  4. 语义分割之Dual Attention Network for Scene Segmentation

    Dual Attention Network for Scene Segmentation 在本文中,我们通过 基于自我约束机制捕获丰富的上下文依赖关系来解决场景分割任务.       与之前通过多尺 ...

  5. 再探go modules:使用与细节

    还有半个月go1.12就要发布了.这是首个将go modules纳入正式支持的稳定版本. 距离go modules随着go1.11正式面向广大开发者进行体验也已经过去了半年,这段时间go module ...

  6. Dual Attention Network for Scene Segmentation

    Dual Attention Network for Scene Segmentation 原始文档 https://www.yuque.com/lart/papers/onk4sn 在本文中,我们通 ...

  7. java并发编程基础-ReentrantLock及LinkedBlockingQueue源码分析

    ReentrantLock是一个较为常用的锁对象.在上次分析的uil开源项目中也多次被用到,下面谈谈其概念和基本使用. 概念 一个可重入的互斥锁定 Lock,它具有与使用 synchronized 相 ...

  8. 并发之AtomicInteger

    并发之AtomicInteger 1 java.util.concurrent.atomic概要     在java.util.concurrent.atomic包下存在着18个类,其中Integer ...

  9. 《Stereo R-CNN based 3D Object Detection for Autonomous Driving》论文解读

    论文链接:https://arxiv.org/pdf/1902.09738v2.pdf 这两个月忙着做实验 博客都有些荒废了,写篇用于3D检测的论文解读吧,有理解错误的地方,烦请有心人指正). 博客原 ...

随机推荐

  1. (六十四)iOS的socket实现(C+OC混合实现)

    对于微博.微信朋友圈之类的网络通信,使用JSON完全可以满足需求,但是如果要制作网络游戏,就需要建立一个持久连接,这时候就要考虑使用socket. 在iOS上实现socket大体有两种方法,一是借助自 ...

  2. HTML5 预加载

    原文地址: HTML5 Link Prefetching 原文日期: 2010年07月07日 翻译日期: 2013年08月13日 浏览器厂商和开发者之间共同努力的一个方向就是让网站更快.现在已有很多广 ...

  3. mysql删除重复数据只保留一条

    mysql删除重复数据只保留一条 新建一张测试表: CREATE TABLE `book` ( `id` char(32) NOT NULL DEFAULT '', `name` varchar(10 ...

  4. 阿里电话面试问题----100万个URL如何找到出现频率最高的前100个?

    内推阿里电话面试中面试官给我出的一个题: 我想的头一个解决方案,就是放到stl 的map里面对出现的频率作为pair的第二个字段进行排序,之后按照排序结果返回: 下面口说无凭,show your co ...

  5. python 多窗口编辑

    同时打开多个文件: 1,vim filename1 filename2 在打开的多个文件中 :next 转到下个文件中 :prev 转到上个文件中 :last/:first 分别到最后一个和第一个文件 ...

  6. Css技术入门笔记01

    在学习html的时候,html中的标签都具备了特定功能,或者含义,以及相应的样式效果.可是在有些时候我们可能仅仅希望使用 html标签把要显示的数据封装起来,而不需要任何的样式效果.这时就需要单独的标 ...

  7. Oracle中job的实例

    一.Oracle定时器(Job)各时间段写法汇总 对于DBA来说,数据库Job再熟悉不过了,因为经常要数据库定时的自动执行一些脚本,或做数据库备份,或做数据的提炼,或做数据库的性能优化,包括重建索引等 ...

  8. 阿里云服务器实战(一) : 在Linux下Tomcat7下使用连接池

    云服务器 的环境如下: Tomcat7+MySql5.6 一,如果自定义了程序的文件目录 , 下面的/alidata/xxx 就是自定义的目录 在Linux的Tomcat的server.xml里的Ho ...

  9. (NO.00001)iOS游戏SpeedBoy Lite成形记(十一)

    之前的10篇内容主要实现了选手从起点移动至终点的动作,比较随机的模拟了选手的速度变化,另外完成了选手到达终点时该做的事情. 接下来的几篇中我们进一步完善SpeedBoy Lite项目,使它真正成为一个 ...

  10. LDA主体模型

    一)LDA作用 传统判断两个文档相似性的方法是通过查看两个文档共同出现的单词的多少,如TF-IDF等,这种方法没有考虑到文字背后的语义关联,可能在两个文档共同出现的单词很少甚至没有,但两个文档是相似的 ...