看了Go的源码CAS这块实现和java还是类似的。

关于Java的分析参考:Java使用字节码和汇编语言同步分析volatile,synchronized的底层实现

都是使用汇编指令:LOCK+CMPXCHGL

原因很简单:单核肯定不能发挥Go的高并发性能,Go如果要支持多核,必然遇到并发编程数据可见性的问题,底层必然加锁。

无锁并不等于没有锁,只能说无重量级的锁而已。

Go语言源码:

Go的CAS是调用CompareAndSwapInt32,

golang中的互斥锁定义在src/sync/mutex.go

// Lock locks m.
// If the lock is already in use, the calling goroutine
// blocks until the mutex is available.
func (m *Mutex) Lock() {// Fast path: grab unlocked mutex.if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) {if race.Enabled {race.Acquire(unsafe.Pointer(m))}return}

无锁操作CAS: Compare And Swap 比较并交换。

源码在/src/runtime/internal/atomic/asm_amd64.s

可以看到实际上底层还是通过lock来实现,关于lock可以参考intel处理器指令。

// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.// Note: some of these functions are semantically inlined
// by the compiler (in src/cmd/compile/internal/gc/ssa.go).#include "textflag.h"// bool Cas(int32 *val, int32 old, int32 new)
// Atomically:
//  if(*val == old){
//      *val = new;
//      return 1;
//  } else
//      return 0;
TEXT runtime∕internal∕atomic·Cas(SB),NOSPLIT,$0-17MOVQ  ptr+0(FP), BXMOVL  old+8(FP), AXMOVL  new+12(FP), CXLOCKCMPXCHGL CX, 0(BX)SETEQ  ret+16(FP)RET// bool   runtime∕internal∕atomic·Cas64(uint64 *val, uint64 old, uint64 new)
// Atomically:
//  if(*val == *old){
//      *val = new;
//      return 1;
//  } else {
//      return 0;
//  }
TEXT runtime∕internal∕atomic·Cas64(SB), NOSPLIT, $0-25MOVQ  ptr+0(FP), BXMOVQ  old+8(FP), AXMOVQ  new+16(FP), CXLOCKCMPXCHGQ CX, 0(BX)SETEQ  ret+24(FP)RETTEXT runtime∕internal∕atomic·Casuintptr(SB), NOSPLIT, $0-25JMP    runtime∕internal∕atomic·Cas64(SB)TEXT runtime∕internal∕atomic·CasRel(SB), NOSPLIT, $0-17JMP runtime∕internal∕atomic·Cas(SB)TEXT runtime∕internal∕atomic·Loaduintptr(SB), NOSPLIT, $0-16JMP  runtime∕internal∕atomic·Load64(SB)TEXT runtime∕internal∕atomic·Loaduint(SB), NOSPLIT, $0-16JMP  runtime∕internal∕atomic·Load64(SB)TEXT runtime∕internal∕atomic·Storeuintptr(SB), NOSPLIT, $0-16JMP  runtime∕internal∕atomic·Store64(SB)TEXT runtime∕internal∕atomic·Loadint64(SB), NOSPLIT, $0-16JMP    runtime∕internal∕atomic·Load64(SB)TEXT runtime∕internal∕atomic·Xaddint64(SB), NOSPLIT, $0-24JMP runtime∕internal∕atomic·Xadd64(SB)// bool Casp1(void **val, void *old, void *new)
// Atomically:
//  if(*val == old){
//      *val = new;
//      return 1;
//  } else
//      return 0;
TEXT runtime∕internal∕atomic·Casp1(SB), NOSPLIT, $0-25MOVQ  ptr+0(FP), BXMOVQ  old+8(FP), AXMOVQ  new+16(FP), CXLOCKCMPXCHGQ CX, 0(BX)SETEQ  ret+24(FP)RET// uint32 Xadd(uint32 volatile *val, int32 delta)
// Atomically:
//  *val += delta;
//  return *val;
TEXT runtime∕internal∕atomic·Xadd(SB), NOSPLIT, $0-20MOVQ   ptr+0(FP), BXMOVL  delta+8(FP), AXMOVL    AX, CXLOCKXADDL AX, 0(BX)ADDL   CX, AXMOVL  AX, ret+16(FP)RETTEXT runtime∕internal∕atomic·Xadd64(SB), NOSPLIT, $0-24MOVQ   ptr+0(FP), BXMOVQ  delta+8(FP), AXMOVQ    AX, CXLOCKXADDQ AX, 0(BX)ADDQ   CX, AXMOVQ  AX, ret+16(FP)RETTEXT runtime∕internal∕atomic·Xadduintptr(SB), NOSPLIT, $0-24JMP   runtime∕internal∕atomic·Xadd64(SB)TEXT runtime∕internal∕atomic·Xchg(SB), NOSPLIT, $0-20MOVQ ptr+0(FP), BXMOVL  new+8(FP), AXXCHGL AX, 0(BX)MOVL   AX, ret+16(FP)RETTEXT runtime∕internal∕atomic·Xchg64(SB), NOSPLIT, $0-24MOVQ   ptr+0(FP), BXMOVQ  new+8(FP), AXXCHGQ AX, 0(BX)MOVQ   AX, ret+16(FP)RETTEXT runtime∕internal∕atomic·Xchguintptr(SB), NOSPLIT, $0-24JMP   runtime∕internal∕atomic·Xchg64(SB)TEXT runtime∕internal∕atomic·StorepNoWB(SB), NOSPLIT, $0-16MOVQ   ptr+0(FP), BXMOVQ  val+8(FP), AXXCHGQ AX, 0(BX)RETTEXT runtime∕internal∕atomic·Store(SB), NOSPLIT, $0-12MOVQ  ptr+0(FP), BXMOVL  val+8(FP), AXXCHGL AX, 0(BX)RETTEXT runtime∕internal∕atomic·StoreRel(SB), NOSPLIT, $0-12JMP    runtime∕internal∕atomic·Store(SB)TEXT runtime∕internal∕atomic·Store64(SB), NOSPLIT, $0-16MOVQ   ptr+0(FP), BXMOVQ  val+8(FP), AXXCHGQ AX, 0(BX)RET// void runtime∕internal∕atomic·Or8(byte volatile*, byte);
TEXT runtime∕internal∕atomic·Or8(SB), NOSPLIT, $0-9MOVQ ptr+0(FP), AXMOVB  val+8(FP), BXLOCKORB   BX, (AX)RET// void  runtime∕internal∕atomic·And8(byte volatile*, byte);
TEXT runtime∕internal∕atomic·And8(SB), NOSPLIT, $0-9MOVQ    ptr+0(FP), AXMOVB  val+8(FP), BXLOCKANDB  BX, (AX)RET

这里还有其他处理器的汇编代码:

其实这篇文章写得也还可以:Golang 源代码解析(一) 锁机制的研究

Go语言源码分析CAS的实现和Java如出一辙相关推荐

  1. Android 切换系统语言源码分析

    以前了解Android的多语言实现很简单,可以在不同的语言环境下使用不同的资源,就做好相应的语言适配就好,但是一直没有实际使用过. 最近公司的项目要用到多国语言切换,并且还是和手机上系统设置里面的语言 ...

  2. vitamio官方demo源码分析(1)——MediaPlayerDemo_Video.java分析

    最近在做一个视频监控项目的android客户端,要求用rtsp协议完成视频流的传输,但苦于找到不合适的库.之前考虑过用live555或ffmpeg,但涉及到jni调用,加之不熟悉函数调用顺序,开发难度 ...

  3. Jedis 1.0.0 版 源码分析系列3:JedisPool.java

    2019独角兽企业重金招聘Python工程师标准>>> package redis.clients.jedis;import redis.clients.util.FixedReso ...

  4. Java源码详解二:HashMap源码分析--openjdk java 11源码

    文章目录 HashMap.java介绍 1.HashMap的get和put操作平均时间复杂度和最坏时间复杂度 2.为什么链表长度超过8才转换为红黑树 3.红黑树中的节点如何排序 本系列是Java详解, ...

  5. Android-FixBug热修复框架的使用及源码分析(不发版修复bug)

    前面几篇博文已经介绍了2种热修复框架的使用及源码分析,AndFix兼容性比较好,而Dexposed Art处于Beta版. AndFix和Dexposed都是阿里的开源项目.  Alibaba-And ...

  6. 单例模式在JDK应用的源码分析

    单例模式在JDK应用的源码分析 单例模式在jdk中的源码分析 在我们JDK中,java.lang.Runtime就是经典的单例模式(恶汉式) 代码分析+Debug源码+代码说明 public clas ...

  7. [转载]jQuery1.6.1源码分析系列

    转载:http://www.cnblogs.com/nuysoft/archive/2011/11/14/2248023.html [原创] jQuery1.6.1源码分析系列(停止更新) 作者:nu ...

  8. 常用jdk类库源码分析以及各个包

    常用jdk类库源码分析以及各个包 1.java.lang包 java.lang包 是Java中最常用的包,程序不需要注入,就可以使用该包中的类,利用包中的类可以设计最基本的Java程序. 2.java ...

  9. android agps,Android应用开发Android GPS ——AGPS源码分析及配置

    本文将带你了解Android应用开发Android GPS --AGPS源码分析及配置,希望本文对大家学Android有所帮助. " Android Framework GPS --AGPS ...

最新文章

  1. 在命令行导出MySQL数据到Excel
  2. 图片预览组件PhotoView
  3. 日志管理系统的重要性---怼死你的客户
  4. Java编程 的动态性,第 2部分: 引入反射--转载
  5. js 难点之call,apply实现
  6. JS 日期工具类-基于yDate
  7. 各种品牌进入Bios方式
  8. 【机器学习】支持向量机原理及例题详解
  9. Windows Server Raid磁盘阵列
  10. SLA是什么意思 ?
  11. Gartner点将分布式文件存储,浪潮存储缘何一鸣惊人?
  12. Spring基础学习(一)
  13. 群晖安装Calibre(含格式转换豆瓣元数据推送kindle)221211
  14. Unity3D游戏开发入门学习笔记
  15. 3月27日下午上完毛概后是一节体育课,这学期要考篮球和跳绳
  16. unity摄像机追踪屏幕抖动的问题
  17. linux需要wifi网络认证,无线802.1x认证简介及配置方法
  18. 程序修行从“拔刀术”到“万剑诀”
  19. verilog练习:hdlbits网站上的做题笔记(7)!强烈推荐!
  20. 单相交流调压电路matlab仿真,单相斩控式交流调压电路

热门文章

  1. python多次循环输出_函数的Python循环(多次将输出作为输入重用)
  2. java程序a-z b-y_有一行电文,以按下面规律译成密码: A---Z a---z B---Y b---Y C---X c---x …… 即第1个字母编程第26个字...
  3. oppor17android版本,OPPOR17ColorOS系统怎么样
  4. Java程序启动同时复制resources下文件到jar包同级目录
  5. 【camera】基于YOLO的车辆多维特征识别系统(车色,车品牌,车标,车型)与PYQT实现(课程设计)
  6. 读后感与机翻《从视频中推断力量和学习人类效用》
  7. knn 进行手写数字识别
  8. Linux那些事儿之我是Sysfs(9)sysfs文件系统模型
  9. char和uchar区别
  10. ATS 5.3.0中利用grep得到纯净的配置文件