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

多线程之CAS与synchronized的比较

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

多线程之CAS与synchronized的比较

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

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.

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

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

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