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. SpringBoot简单整合Gateway网关

    引入依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>s ...

  2. c++之面试题(1)

    题目 有十瓶药,每瓶里都装有100片药,其中有八瓶里的药每片重10克,另有两瓶里的药每片重9克.用一个蛮精确的小秤,只称一次,如何找出份量较轻的那两个药瓶? 解法 1.分别给10个药瓶按照斐波那契数列 ...

  3. 【LeetCode】944. Delete Columns to Make Sorted 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  4. 【LeetCode】551. Student Attendance Record I 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 正则表达式 统计 日期 题目地址:https://l ...

  5. 涛思数据 TDengine集群搭建

    一.准备 1.设置主机名 hostnamectl set-hostname a.com hostnamectl set-hostname b.com hostnamectl set-hostname ...

  6. DAGs with NO TEARS: Continuous Optimization for Structure Learning

    DAGs with NO TEARS: Continuous Optimization for Structure Learning 目录 DAGs with NO TEARS: Continuous ...

  7. McGan: Mean and Covariance Feature Matching GAN

    目录 概 主要内容 Mean Matching IPM prime dual Covariance Feature Matching IPM prime dual 算法 代码 Mroueh Y, Se ...

  8. CS5211替代LT7211 DP转LVDS芯片方案 替代龙迅LT7211方案

    LT7211是一种用于虚拟现实/显示应用的高性能C/DP1.2至LVDS芯片方案.LT7211支持DP1.2输入,LT7211可以配置为1.2.4车道,还支持车道交换功能.自适应均衡使其适用于长电缆应 ...

  9. FP增长算法

    Apriori原理:如果某个项集是频繁的,那么它的所有子集都是频繁的. Apriori算法: 1 输入支持度阈值t和数据集 2 生成含有K个元素的项集的候选集(K初始为1) 3 对候选集每个项集,判断 ...

  10. Drools集成SpringBoot

    1.说明 为了更好的在项目中使用Drools, 需要把Drools集成到Spring Boot, 下面介绍集成的方法, 并且开发简单的Demo和测试用例. 2.创建Maven工程 pom.xml工程信 ...