atomic

iOS开发多线程篇---atomic nonatomic区别

倖福魔咒の 提交于 2020-04-20 07:46:09
atomic :默认是有该属性的,这个属性是为了保证程序在多线程情况下,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题。 nonatomic :如果该对象无需考虑多线程的情况,请加入这个属性,这样会让编译器少生成一些互斥加锁代码,可以提高效率。 atomic的意思就是setter/getter这个函数,是一个原语操作。如果有多个线程同时调用setter的话,不会出现某一个线程执行完setter全部语句之前,另一个线程开始执行setter情况,相当于函数头尾加了锁一样,可以保证数据的完整性。 nonatomic不保证setter/getter的原语行,所以你可能会取到不完整的东西。因此 ,在多线程的环境下原子操作是非常必要的,否则有可能会引起错误的结果。 比如setter函数里面改变两个成员变量,如果你用nonatomic的话,getter可能会取到只更改了其中一个变量时候的状态,这样取到的东西会有问题,就是不完整的。当然 如果不需要多线程支持的话,用nonatomic就够了,因为不涉及到线程锁的操作,所以它执行率相对快些。 下面是载录的网上一段加了atomic的例子: {lock} if (property != newValue) { [property release]; property = [newValue retain]; } {unlock} 可以看出来

Java中的volatile关键字实现原理深度解析

穿精又带淫゛_ 提交于 2020-04-19 01:56:00
  在Java语言规范中对volatile的定义如下:Java编程语言中允许线程访问共享变量,为了确保共享变量能被准确和一致的更新,线程应该确保通过排他锁来确保单独获取这个变量。Java还提提供了volatile关键字,在某些情况下比锁更加方便。   volatile关键字可以说是java虚拟机中提供的最轻量级的同步机制,但它并不是锁。因此,在使用时,只有真正明白它的特性、原理才能正确的使用volatile。 0 与volatile实现相关的CPU术语 术语 英文单词 术语描述 内存屏障 memory barriers 是一组处理器指令,用于实现对内存操作的顺序限制 缓冲行 cache line 缓存中可以分配的最小存储单位。处理器填写缓存线时会加载整个缓存线,需要使用多个主内存读周期 原子操作 atomic operation 不可中断的一个或一系列操作 缓存行填充 cache line fill 当处理器识别到从内存中读取操作数时可缓存的,处理器读取真哥哥缓存行到适当的缓存(L1,L2,L3或所有) 缓存命中 cache hit 如果进行高速缓存行填充操作的内存位置仍然是下次处理器访问的地址时,处理器从缓存中读取操作数,而不是从内存读取 写命中 write hit 当处理器将操作数写回到一个内存缓存的区域时,它首先回检查这个缓存的内存地址是否在缓存行中,如果存在一个有效的缓存行

Java中的volatile关键字实现原理深度解析

点点圈 提交于 2020-04-19 01:30:56
  在Java语言规范中对volatile的定义如下:Java编程语言中允许线程访问共享变量,为了确保共享变量能被准确和一致的更新,线程应该确保通过排他锁来确保单独获取这个变量。Java还提提供了volatile关键字,在某些情况下比锁更加方便。   volatile关键字可以说是java虚拟机中提供的最轻量级的同步机制,但它并不是锁。因此,在使用时,只有真正明白它的特性、原理才能正确的使用volatile。 0 与volatile实现相关的CPU术语 术语 英文单词 术语描述 内存屏障 memory barriers 是一组处理器指令,用于实现对内存操作的顺序限制 缓冲行 cache line 缓存中可以分配的最小存储单位。处理器填写缓存线时会加载整个缓存线,需要使用多个主内存读周期 原子操作 atomic operation 不可中断的一个或一系列操作 缓存行填充 cache line fill 当处理器识别到从内存中读取操作数时可缓存的,处理器读取真哥哥缓存行到适当的缓存(L1,L2,L3或所有) 缓存命中 cache hit 如果进行高速缓存行填充操作的内存位置仍然是下次处理器访问的地址时,处理器从缓存中读取操作数,而不是从内存读取 写命中 write hit 当处理器将操作数写回到一个内存缓存的区域时,它首先回检查这个缓存的内存地址是否在缓存行中,如果存在一个有效的缓存行

Goroutine被动调度之一(18)

荒凉一梦 提交于 2020-04-18 10:05:33
本文是《Go语言调度器源代码情景分析》系列的第18篇,也是第四章《Goroutine被动调度》的第1小节。 前一章我们详细分析了调度器的调度策略,即调度器如何选取下一个进入运行的goroutine,但我们还不清楚什么时候以及什么情况下会发生调度,从这一章开始我们就来讨论这个问题。 总体说来,go语言的调度器会在以下三种情况下对goroutine进行调度: goroutine执行某个操作因条件不满足需要等待而发生的调度; goroutine主动调用Gosched()函数让出CPU而发生的调度; goroutine运行时间太长或长时间处于系统调用之中而被调度器剥夺运行权而发生的调度。 本章主要分析我们称之为被动调度的第1种调度,剩下的两种调度将在后面两章分别进行讨论。 Demo例子 我们以一个demo程序为例来分析因阻塞而发生的被动调度。 package main func start(c chan int) { c<-100 } func main() { c:=make(chan int) go start(c) <-c } 该程序启动时,main goroutine首先会创建一个无缓存的channel,然后启动一个goroutine(为了方便讨论我们称它为g2)向channel发送数据,而main自己则去读取这个channel。

蘑菇街Java大牛纯手打肛出的一份多线程文档,请别丢进收藏夹吃灰

Deadly 提交于 2020-04-17 22:19:25
前言 这个【多线程】的文档是全程手打肛出来的,共129页,希望各位老铁可以转发本文支持一下! 完整版多线程文档资料领取方式:加我VX【tkzl6666】获得免费领取方式。领取之后可别丢进收藏夹吃灰喔! 内容介绍 一、什么是多线程 1.初识多线程 1.1介绍进程 1.2回到线程 1.3进程与线程 1.4并行与并发 1.5Java实现多线程 1.5.1继承Thread,重写run方法 1.5.2实现Runnable接口,重写run方法 1.6Java实现多线程需要注意的细节 二、Thread类解析 1.Thread线程类API 1.1设置线程名 1.2守护线程 1.3优先级线程 1.4线程生命周期 1.4.1sleep方法 1.4.2yield方法 1.4.3join方法 1.4.3interrupt方法 三、使用多线程需要注意的问题 1、使用多线程遇到的问题 1.1线程安全问题 1.3性能问题 2、对象的发布与逸出 2.1安全发布对象 3、解决多线程遇到的问题 3.1简述解决线程安全性的办法 3.2原子性和可见性 3.2.1原子性 3.2.2可见性 3.3线程封闭 3.4不变性 3.5线程安全性委托 4、多线程需要注意的事 -总结 四、synchronized锁和lock锁 1、synchronized锁 1.1synchronized锁是什么? 1

GitHub

寵の児 提交于 2020-04-17 07:33:05
【推荐阅读】微服务还能火多久?>>> uber-go/guide 的中文翻译 English Uber Go 语言编码规范 Uber 是一家美国硅谷的科技公司,也是 Go 语言的早期 adopter。其开源了很多 golang 项目,诸如被 Gopher 圈熟知的 zap 、 jaeger 等。2018 年年末 Uber 将内部的 Go 风格规范 开源到 GitHub,经过一年的积累和更新,该规范已经初具规模,并受到广大 Gopher 的关注。本文是该规范的中文版本。本版本会根据原版实时更新。 版本 当前更新版本:2020-02-25 版本地址: commit:#86 如果您发现任何更新、问题或改进,请随时 fork 和 PR Please feel free to fork and PR if you find any updates, issues or improvement. 目录 介绍 指导原则 指向 interface 的指针 Interface 合理性验证 接收器 (receiver) 与接口 零值 Mutex 是有效的 在边界处拷贝 Slices 和 Maps 使用 defer 释放资源 Channel 的 size 要么是 1,要么是无缓冲的 枚举从 1 开始 使用 "time" 处理时间 错误类型 错误包装 (Error Wrapping) 处理类型断言失败

compiler reordering vs memory reordering

江枫思渺然 提交于 2020-04-15 15:22:22
问题 Under gcc there are the followings instructions available for set a memory barrier. They both provide different "protection" asm volatile("" ::: "memory"); // compiler reorder asm volatile("mfence" ::: "memory"); // memory reordering C++ atomic provide in short : - acquire/release semantics - Sequentially-consistent ordering I'm wondering if there is a direct mapping between gcc primitive and C++ atomic semantics ? (for instance (that must be wrong,it's just for explanation purpose) , acquire

compiler reordering vs memory reordering

放肆的年华 提交于 2020-04-15 15:20:14
问题 Under gcc there are the followings instructions available for set a memory barrier. They both provide different "protection" asm volatile("" ::: "memory"); // compiler reorder asm volatile("mfence" ::: "memory"); // memory reordering C++ atomic provide in short : - acquire/release semantics - Sequentially-consistent ordering I'm wondering if there is a direct mapping between gcc primitive and C++ atomic semantics ? (for instance (that must be wrong,it's just for explanation purpose) , acquire

CAS 以及它在java中的体现

限于喜欢 提交于 2020-04-13 20:35:17
【今日推荐】:为什么一到面试就懵逼!>>> Compare And Swap:比较和交换 v(内存位置) a(旧的期望值) b(改变之后的值) 数据在修改之前,旧的预期值和v中的值一致时,才能修改 java中Atomic相关类就是使用的这种算法实现的。 它和Synchronized相对: Synchoronized属于悲观锁,认为并发数据操作是一个大概率事件(总有刁民想害朕),我操作的时候,得把数据锁上,别人谁也别想动 而CAS属于乐观锁,它认为并发数据操作是小概率事件,你操作数据之后我再核查一遍,现在的数据和我修改的时候,读取的数据是否一致就没事了,通过比较和交换的方式进行数据修改。 拿 AtomicInteger 的 incrementAndGet 方法举例,这个方法就是给当前对象的数值+1,但是保证了线程安全: public void test(){ AtomicInteger atomicInteger = new AtomicInteger(1); atomicInteger.incrementAndGet (); Integer integer = 1; integer = integer + 1; // 以上两种操作,结果是一样的 } 看看CAS再JDK1.8中是怎么实现的: public final int incrementAndGet() { //

springboot + aop + Lua分布式限流原理解析

时光怂恿深爱的人放手 提交于 2020-04-13 09:15:52
【今日推荐】:为什么一到面试就懵逼!>>> 一、什么是限流?为什么要限流? 不知道大家有没有做过帝都的地铁,就是进地铁站都要排队的那种,为什么要这样摆长龙转圈圈?答案就是为了 限流 !因为一趟地铁的运力是有限的,一下挤进去太多人会造成站台的拥挤、列车的超载,存在一定的安全隐患。同理,我们的程序也是一样,它处理请求的能力也是有限的,一旦请求多到超出它的处理极限就会崩溃。为了不出现最坏的崩溃情况,只能耽误一下大家进站的时间。 限流是保证系统高可用的重要手段!!! 由于互联网公司的流量巨大,系统上线会做一个流量峰值的评估,尤其是像各种秒杀促销活动,为了保证系统不被巨大的流量压垮,会在系统流量到达一定阈值时,拒绝掉一部分流量。 限流会导致用户在短时间内(这个时间段是毫秒级的)系统不可用,一般我们衡量系统处理能力的指标是每秒的 QPS 或者 TPS ,假设系统每秒的流量阈值是1000,理论上一秒内有第1001个请求进来时,那么这个请求就会被限流。 二、限流方案 1、计数器 Java内部也可以通过原子类计数器 AtomicInteger 、 Semaphore 信号量来做简单的限流。 // 限流的个数 private int maxCount = 10; // 指定的时间内 private long interval = 60; // 原子类计数器 private AtomicInteger