摘要: 一、前言 go语言类似Java JUC包也提供了一些列用于多线程之间进行同步的措施,比如低级的同步措施有 锁、CAS、原子变量操作类。相比Java来说go提供了独特的基于通道的同步措施。本节我们先来看看go中CAS操作 二、CAS操作 go中的Cas操作与java中类似,都是借用了CPU提供的原子性指令来实现。

一、前言

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

二、CAS操作

go中的Cas操作与java中类似,都是借用了CPU提供的原子性指令来实现。CAS操作修改共享变量时候不需要对共享变量加锁,而是通过类似乐观锁的方式进行检查,本质还是不断的占用CPU 资源换取加锁带来的开销(比如上下文切换开销)。下面一个例子使用CAS来实现计数器

package main
import (
    "fmt"
    "sync"
    "sync/atomic"
)

var (
    counter int32          //计数器
    wg      sync.WaitGroup //信号量
)

func main() {

    threadNum := 5

    //1. 五个信号量
    wg.Add(threadNum)

    //2.开启5个线程
    for i := 0; i < threadNum; i++ {
        go incCounter(i)
    }

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

func incCounter(index int) {
    defer wg.Done()

    spinNum := 0
    for {
        //2.1原子操作
        old := counter
        ok := atomic.CompareAndSwapInt32(&counter, old, old+1)
        if ok {
            break
        } else {
            spinNum++
        }
    }

    fmt.Printf("thread,%d,spinnum,%d\n",index,spinNum)

}
  • 如上代码main线程首先创建了5个信号量,然后开启五个线程执行incCounter方法
  • incCounter内部执行代码2.1 使用cas操作递增counter的值, atomic.CompareAndSwapInt32具有三个参数,第一个是变量的地址,第二个是变量当前值,第三个是要修改变量为多少,该函数如果发现传递的old值等于当前变量的值,则使用第三个变量替换变量的值并返回true,否则返回false。
  • 这里之所以使用无限循环是因为在高并发下每个线程执行CAS并不是每次都成功,失败了的线程需要重写获取变量当前的值,然后重新执行CAS操作。读者可以把线程数改为10000或者更多会发现输出thread,5329,spinnum,1其中1说明该线程尝试了两个CAS操作,第二次才成功。

三、总结

go中CAS操作具有原子性,在解决多线程操作共享变量安全上可以有效的减少使用锁所带来的开销,但是这是使用cpu资源做交换的。

我简单的列举了并发的大纲,需要详细的可进群学习咨询:836442475(大牛聚集地)一起交流学习探讨!

Go并发编程之美-CAS操作的更多相关文章

  1. java并发编程之美-阅读记录1

    1.1什么是线程? 在理解线程之前先要明白什么是进程,因为线程是进程中的一个实体.(线程是不会独立存在的) 进程:是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,线程则是进程中的 ...

  2. java并发编程之美-阅读记录7

    java并发包中的并发队列 7.1ConcurrentLinkedQueue 线程安全的无界非阻塞队列(非阻塞队列使用CAS非阻塞算法实现),其底层数组使用单向列表实现,对于出队和入队操作使用CAS非 ...

  3. Java并发--Java中的CAS操作和实现原理

    版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/CringKong/article/deta ...

  4. java并发编程之美-阅读记录2

    2.1什么是多线程并发编程 并发:是指在同一时间段内,多个任务同时在执行,并且执行没有结束(同一时间段又包括多个单位时间,也就是说一个cpu执行多个任务) 并行:是指在单位时间内多个任务在同时执行(也 ...

  5. 并发编程的基石——CAS机制

    本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 Java中提供了很多原子操作类来保证共享变量操作的原子性 ...

  6. 【C# 线程】并发编程的基石——CAS机制

    其实Java并发框架的基石一共有两块,一块是本文介绍的CAS,另一块就是AQS,后续也会写博客介绍. 什么是CAS机制 CAS机制是一种数据更新的方式.在具体讲什么是CAS机制之前,我们先来聊下在多线 ...

  7. java并发编程之美-阅读记录11

    java并发编程实践 11.1ArrayBlockingQueue的使用 有关logback异步日志打印中的ArrayBlockingQueue的使用 1.异步日志打印模型概述 在高并发.高流量并且响 ...

  8. java并发编程之美-阅读记录4

    java并发包中的原子操作类,这些类都是基于非阻塞算法CAS实现的. 4.1原子变量操作类 AtomicInteger/AtomicLong/AtomicBoolean等原子操作类 AtomicLon ...

  9. 34、python并发编程之多进程(操作篇)

    目录: 一 multiprocessing模块介绍 二 Process类的介绍 三 Process类的使用 四 守护进程 五 进程同步(锁) 六 队列(推荐使用) 七 管道 八 共享数据 九 信号量( ...

随机推荐

  1. Python SMTP发送邮件

    import smtplibfrom email.mime.text import MIMEText  # 引入smtplib和MIMEText host = 'smtp.163.com'  # 设置 ...

  2. pythone函数基础(10)MD5加密

    导入hashlib模块import hashlibs='yulin123456's.encode()#把数字转换成bytes类型m=hashlib.md5(s.encode())print(m.hex ...

  3. SpringAOP日志配置

    SpringAOP日志配置 配置文件配置 l  配置spring-mvc.xml <aop:config proxy-target-class="true" /> &l ...

  4. 使用jmail发送短信

    原文链接 https://blog.csdn.net/sdaujsj1/article/details/79248469 pom <!-- https://mvnrepository.com/a ...

  5. 英雄联盟lol登录错误:登录服务器未响应、您可能遇到了一个网络问题、请检查您的网络。

    第一方法cmd 用管理员命令打开,输入  netsh winsock reset.重启 第二种方法  win+r 输入 regedit  在 HKEY_CURRENT_USER\Software\Mi ...

  6. webapi 重复提交问题

    https://izen.live/Blog/info/13.html /// <summary> /// action方法过滤器 /// </summary> public ...

  7. 201621123002《JAVA程序设计》第二周学习总结

    1.本周学习总结 1.重点String类 2.Java的数据类型 3.Java中的引用类,包装类 for(类型 元素变量名(任取):遍历对象(数组名)) 2.书面作业 1.String-使用Eclip ...

  8. TerraGate SFS Manager配置时权限设置问题

    配置SFS Manager时出现以下错误:      "windows account(*\ASPNET) that does not have sufficient permissions ...

  9. Unittest中TestCase类中定义的几个特殊方法

    1.setUp():每个测试方法运行前运行,测试前的初始化工作: 2.tearDown():每个测试方法运行结束后运行,测试后的清理工作: 3.setUpClass():所有的测试方法运行前运行,单元 ...

  10. 第39章:MongoDB-集群--Replica Sets(副本集)---副本集基本原理

    ①操作日志oplog Oplog是主节点的local数据库中的一个固定集合,按顺序记录了主节点的每一次写操作,MongoDB的复制功能是使用oplog来实现的,备份节点通过查询这个集合就可以知道需要进 ...