多线程之CAS与synchronized的比较
发布日期:2022-04-11 08:52:45 浏览次数:14 分类:技术文章

本文共 1068 字,大约阅读时间需要 3 分钟。

业务场景:需要实现一个支持并发的计数功能

1、计数功能的基本实现是:

public class Increment{
  private int count = 0;  public void add(){
   count++;   }}

2、以上实现在并发环境下是不安全的,故修改方案1是加锁synchronized:

public class Increment{
  private int count = 0;  public synchronized void add(){
   count++;    }}

//悲观锁,加锁后只能有一个线程你执行++操作,其他线程需要等待

//不会出现count计数不准确的问题,线程安全

3、但是以上实现,会让线程串行化,排队等待获取锁、加锁、处理数据、释放锁,并发下显得不合理

修改方案2是使用Java并发包concurrent下的Atomic原子类

public class Increment{
  private AtomicInteger count = new AtomicInteger();  public synchronized void add(){
    count.incrementAndGet();  }}

//多个线程可以并发的执行AtomicInteger的incrementAndGet()方法,把count的值累加1并返回累加后最新的值

//Atomic原子类底层用的是无锁化的CAS机制,保证多线程修改一个数值的安全性

4、实现原理:

(1)每个线程都会先获取当前的值,接着走一个原子的CAS操作,原子的意思就是这个CAS操作一定是自己完整执行完的,不会被别人打断;

(2)在CAS操作里,比较一下,现在的值跟刚才我获取到的那个值,是否相等,是则说明没有人改过这个值,那么将它设置成累加1之后的一个值;

(3)同理,若有人在执行CAS时,发现自己之前获取的值与当前的值不一样,说明有其他人修改了值,导致CAS失败,失败之后进入一个循环,再次获取值,再执行CAS操作。

5、CAS的问题:

每次去比较的时候,都发现值被别人改了,就会进入无限重复的循环。大量线程高并发时相当于空循环,自旋转,性能和效率都不是特别好。

Java8的新类LongAdder,尝试使用分段CAS以及自动分段迁移的方式来提升多线程高并发执行CAS操作的性能。核心思想是热点分离,类似concurrentHashMap.

转载地址:https://lebron.blog.csdn.net/article/details/122906450 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:多线程之sleep和wait的区别
下一篇:多线程之callable详解

发表评论

最新留言

很好
[***.229.124.182]2024年04月23日 22时38分03秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章