1. 概念
原子操作 atomic 包
加锁操作涉及到内核态的上下文切换,比较耗时,代价高,
针对基本数据类型我们还可以使用原子操作来保证并发的安全,
因为原子操作是go语言提供的方法,我们在用户态就可以完成,因此性能比加锁操作更好
go语言的原子操作由内置的库 sync/atomic 完成

2. atomic包
方法 解释
func LoadInt32(addr int32) (val int32)
func LoadInt64(addr `
int64) (val int64)<br>func LoadUint32(addruint32) (val uint32)<br>func LoadUint64(addruint64) (val uint64)<br>func LoadUintptr(addruintptr) (val uintptr)<br>func LoadPointer(addrunsafe.Pointer`) (val unsafe.Pointer)
读取操作
func StoreInt32(addr *int32, val int32)
func StoreInt64(addr *int64, val int64)
func StoreUint32(addr *uint32, val uint32)
func StoreUint64(addr *uint64, val uint64)
func StoreUintptr(addr *uintptr, val uintptr)
func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)
写入操作
func AddInt32(addr *int32, delta int32) (new int32)
func AddInt64(addr *int64, delta int64) (new int64)
func AddUint32(addr *uint32, delta uint32) (new uint32)
func AddUint64(addr *uint64, delta uint64) (new uint64)
func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
修改操作
func SwapInt32(addr *int32, new int32) (old int32)
func SwapInt64(addr *int64, new int64) (old int64)
func SwapUint32(addr *uint32, new uint32) (old uint32)
func SwapUint64(addr *uint64, new uint64) (old uint64)
func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)
func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)
交换操作
func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)
func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)

3. 案例比较互斥锁和原子操作的性能

package main

import (
"fmt"
"sync"
"sync/atomic"
"time"
) var (
x int64
mx sync.Mutex
wg sync.WaitGroup
) // 普通函数,并发不安全
func Add() {
x++
wg.Done()
}
// 互斥锁,并发安全,性能低于原子操作
func MxAdd() {
mx.Lock()
x++
mx.Unlock()
wg.Done()
}
// 原子操作,并发安全,性能高于互斥锁,只针对go中的一些基本数据类型使用
func AmAdd() {
atomic.AddInt64(&x, 1)
wg.Done()
} func main() {
// 原子操作 atomic 包
// 加锁操作涉及到内核态的上下文切换,比较耗时,代价高,
// 针对基本数据类型我们还可以使用原子操作来保证并发的安全,
// 因为原子操作是go语言提供的方法,我们在用户态就可以完成,因此性能比加锁操作更好
// go语言的原子操作由内置的库 sync/atomic 完成 start := time.Now()
for i := 0; i < 10000; i++ {
wg.Add(1)
//go Add() // 普通版Add函数不是并发安全的
//go MxAdd() // 加锁版Add函数,是并发安全的,但是加锁性能开销大
go AmAdd() // 原子操作版Add函数,是并发安全的,性能优于加锁版
} end := time.Now()
wg.Wait()
fmt.Println(x)
fmt.Println(end.Sub(start)) }

 atomic包提供了底层的原子级内存操作,对于同步算法的实现很有用,这些函数必须谨慎的保证正确使用,除了某些特殊的底层应用,使用通道或者sync包的函数/类型实现同步更好

golang中的原子操作atomic包的更多相关文章

  1. 什么是Java中的原子操作( atomic operations)

    1.啥是java的原子性 原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行. 一个很经典的例子就是银行账户转账问题: 比如从账户A向账户B转1000元,那么 ...

  2. golang语言中sync/atomic包的学习与使用

    package main; import ( "sync/atomic" "fmt" "sync" ) //atomic包提供了底层的原子级 ...

  3. golang中tcp socket粘包问题和处理

    转自:http://www.01happy.com/golang-tcp-socket-adhere/ 在用golang开发人工客服系统的时候碰到了粘包问题,那么什么是粘包呢?例如我们和客户端约定数据 ...

  4. golang中的net/rpc包

    本文先介绍RPC,然后go原生对RPC的使用,之后是介绍go语言中有哪些RPC框架以及一些其他常见的框架,最后是探究go语言中rpc的源码. (1)首先介绍下什么RPC? (2)RPC可以做什么? ( ...

  5. Java中的Atomic包

    Atomic包的作用 方便程序员在多线程环境下,无锁的进行原子操作 Atomic包核心 Atomic包里的类基本都是使用Unsafe实现的包装类,核心操作是CAS原子操作: 关于CAS compare ...

  6. java.util.concurrent.atomic 包详解

    Atomic包的作用: 方便程序员在多线程环境下,无锁的进行原子操作 Atomic包核心: Atomic包里的类基本都是使用Unsafe实现的包装类,核心操作是CAS原子操作 关于CAS compar ...

  7. golang中并发sync和channel

    golang中实现并发非常简单,只需在需要并发的函数前面添加关键字"go",但是如何处理go并发机制中不同goroutine之间的同步与通信,golang 中提供了sync包和channel ...

  8. 24.Java中atomic包中的原子操作类总结

    1. 原子操作类介绍 在并发编程中很容易出现并发安全的问题,有一个很简单的例子就是多线程更新变量i=1,比如多个线程执行i++操作,就有可能获取不到正确的值,而这个问题,最常用的方法是通过Synchr ...

  9. Java中Atomic包的实现原理及应用

    1. 同步问题的提出 假设我们使用一个双核处理器执行A和B两个线程,核1执行A线程,而核2执行B线程,这两个线程现在都要对名为obj的对象的成员变量i进行加1操作,假设i的初始值为0,理论上两个线程运 ...

随机推荐

  1. c++之折半查找(二分查找)递归与非递归的实现

    递归实现 template<typename T> int binary_search2(const T arr[], const int left, const int right, c ...

  2. MFC屏蔽按键ESC、ENTER、Alt+F4

    1.重写 重写下面的函数 virtual BOOL PreTranslateMessage(MSG* pMsg); 2.函数体 BOOL Cfile_trans_codeDlg::PreTransla ...

  3. 【LeetCode】4. Median of Two Sorted Arrays 寻找两个正序数组的中位数

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:数组,中位数,题解,leetcode, 力扣,python ...

  4. 【LeetCode】414. Third Maximum Number 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 替换最大值数组 使用set 三个变量 日期 题目地址 ...

  5. 使用PyTorch构建神经网络模型进行手写识别

    使用PyTorch构建神经网络模型进行手写识别 PyTorch是一种基于Torch库的开源机器学习库,应用于计算机视觉和自然语言处理等应用,本章内容将从安装以及通过Torch构建基础的神经网络,计算梯 ...

  6. 【优雅代码】02-java传个方法你会吗,不是Method对象

    [优雅代码]02-java传个方法你会吗,不是Method对象 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮 ...

  7. 使用 Android Studio 开发工具创建一个 Android 应用程序,并在 Genymotion 模拟器上运行

    需求说明: 使用 Android Studio 开发工具创建一个 Android 应用程序,并在 Genymotion 模拟器上运行 实现步骤: 打开 Android Studio,创建一个 Andr ...

  8. Java高级程序设计笔记 • 【第4章 网络编程】

    全部章节   >>>> 本章目录 4.1 网络基础知识 4.1.1 IP地址 4.1.2 端口号 4.1.3 使用InetAddress 4.1.4 InetAddress 类 ...

  9. AVD Pixel_2_API_30 is already running. lf that is not the case, delete the files at

    AVD Pixel_2_API_30 is already running. lf that is not the case, delete the files at C:\Users\Adminis ...

  10. Windows环境下使用Linux命令

    1.说明 如何在Windows环境下使用Linux命令, 这是一个屡见不鲜的问题, 而且已经有很多解决方法, 下面仅推荐几个我觉得好用的工具, 这些工具可能就是我们常用的软件, 而且已经在Window ...