栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

CAS机制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

CAS机制

CAS机制
  • 乐观锁与悲观锁
  • CAS的例子

乐观锁与悲观锁

悲观锁:多个线程操作同一个资源对象,使用互斥锁来实现线程之间的同步。
操作系统会悲观的认为如果不进行严格的线程调用,将发生异常。
所以每次只允许一个线程进行占用,阻塞其他线程。

乐观锁:不锁定资源也能同步线程。一个线程去修改一个资源的状态的时候总是乐观的认为对象状态值没有被修改过。利用CAS(Compare And Swap)机制。CAS需要有3个操作数:内存地址,旧的预期值,将要更新的目标值。
多个线程同时到达,进行读取数据为Old Value,代表之前读到的资源对象的状态值,New Value代表想要对该数据修改后的值。假设A线程率先获得时间片,比较Old Value是否一致,一致则进行修改。B线程也进行该操作发现Old Value不一致就不断进行CAS操作,也叫做自旋,一般会设定一个自选次数的值来防止死锁。

乐观锁与悲观锁的比较:悲观锁调用操作系统底层的同步原语比如mutex,性能较低。乐观锁则减少了操作系统用户态与系统态之间的切换,提升了多线程并发的性能,但是无锁编程难度更高并且控制更加复杂容易出错。CAS操作必须是原子性的!

CAS的例子

需求:使用三个线程对1000以内的数进行打印
可以使用加锁或者CAS,这里使用CAS来进行线程同步
代码以及输出:


AtomicInteger源码


一个long类型的对象一个Unsafe的对象。

Java语言不像C,C++那样可以直接访问底层操作系统,但是JVM为我们提供了一个后门,这个后门就是unsafe。unsafe为我们提供了硬件级别的原子操作。
至于valueOffset对象,是通过unsafe.objectFiledOffset方法得到,所代表的是AtomicInteger对象value成员变量在内存中的偏移量。我们可以简单的把valueOffset理解为value变量的内存地址。
AtomicInteger对象的incrementAndGet()调用地实际上是Unsafe对象的getAddAddInt()方法。

Unsafe对象的getAddAddInt()方法里面的while实际上就是一个自旋操作,可以设定自旋次数,不配置的话默认是10,不会出现死循环。
用volatile关键字来保证(保证线程间的可见性)获取的当前值是内存中的最新值。

compareAndSwapInt()是一个本地方法,操作是原子性的,与平台实现有关。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/583974.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号