CAS -> unsafe -> CAS底层思想 -> ABA --> 原子引用更新 --> 如何规避ABA

CAS compareAndSwap 原理

CAS(V,E,N) V表示要更新的变量(内存值)   E表示预期值   N表示新值 (当前值和底层值一样时候,才更新)

传入的值是工作内存,底层的值是主内存,工作内存和主内存不一定是同步的,在某一时间点会同步相同。所以CAS不断尝试,等待他们相同后在操作。

网上的方法实现(理解即可)

public final int getAndAddInt(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return next;
}
}
假设delta的值为1,在CAS算法下操作的话,首先进入一个for循环体;假设存在着两个线程,并且内存中的值value=3;根据Java内存模型,每一个线程都存在这这个变量的副本;
    1) 线程1进入循环体,获取到current的值为3,然后获取到到next的值此时为4;此时假设线程1运气不好,被挂起;
    2) 线程2进入循环体,获取到current的值为3,同时next的值也为4;线程2运气好,此时继续执行。 线程2传入两个参数,一个当前值,以及一个预期值;当前值,也就是current=3.要修改成为4;此时当前值也就是预期值和内存中的value比较,此时都是3,那么修改内存中的值为4;
    3)线程1此时再次执行compareAndSwapInt()方法的时候。发现内存中的值为4,预期的值是3,两者不相等,此时就不可以再次赋值
 

CAS的问题

1. 循环时间长开销大: 自旋CAS(不成功,就一直循环执行,直到成功), 并发高的时候耗费CPU.

2. ABA问题  : 如果一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化。解决思路使用版本号。在变量前面追加上版本号,每次变量更新的时候把版本号加一,那么A-B-A 就会变成1A-2B-3A。Java8 AtomicInteger 使用 AtomicStampReference 来解决增加版本号。

3. 只能保证一个共享变量的原子操作

  CAS与Synchronized的使用情景:   

1、对于资源竞争较少(线程冲突较轻)的情况,使用synchronized同步锁进行线程阻塞和唤醒切换以及用户态内核态间的切换操作额外浪费消耗cpu资源;而CAS基于硬件实现,不需要进入内核,不需要切换线程,操作自旋几率较少,因此可以获得更高的性能。

2、对于资源竞争严重(线程冲突严重)的情况,CAS自旋的概率会比较大,从而浪费更多的CPU资源,效率低于synchronized。

补充: synchronized在jdk1.6之后,已经改进优化。synchronized的底层实现主要依靠Lock-Free的队列,基本思路是自旋后阻塞,竞争切换后继续竞争锁,稍微牺牲了公平性,但获得了高吞吐量。在线程冲突较少的情况下,可以获得和CAS类似的性能;而线程冲突严重的情况下,性能远高于CAS。

Synchronized -  锁 类对象和实例

class Test{
// 以下两个方法是等价的,都是锁住了 new Test()的实例
public void a0() {
synchronized(this) {
}
} public synchronized void a() {
}
}

锁住类

class Test {
// 以下两个方法是等价的
public static void a() {
// 因为是静态方法,共享与不同的线程,所以这里需要锁住整个Test类型,不再是实例
synchronized(Test.class) {
}
} public synchronized static void a() {
}
}

子类不会继承父类的Synchronize方法, 因为Synchronized不属于方法签名。

参考文档

https://www.cnblogs.com/Leo_wl/p/6899716.html

https://blog.csdn.net/tiandao321/article/details/80811103

https://www.cnblogs.com/gosaint/p/9045494.html

https://blog.csdn.net/mmoren/article/details/79185862

CAS和Synchronized的更多相关文章

  1. 【并发编程】【JDK源码】CAS与synchronized

    线程安全 众所周知,Java是多线程的.但是,Java对多线程的支持其实是一把双刃剑.一旦涉及到多个线程操作共享资源的情况时,处理不好就可能产生线程安全问题.线程安全性可能是非常复杂的,在没有充足的同 ...

  2. 并发的核心:CAS 与synchronized, Java8是如何优化 CAS 的?

    大家可能都听说说 Java 中的并发包,如果想要读懂 Java 中的并发包,其核心就是要先读懂 CAS 机制,因为 CAS 可以说是并发包的底层实现原理. 今天就带大家读懂 CAS 是如何保证操作的原 ...

  3. 基础篇:详解锁原理,volatile+cas、synchronized的底层实现

    目录 1 锁的分类 2 synchronized底层原理 3 Object的wait和notify方法原理 4 jvm对synchronized的优化 5 CAS的底层原理 6 CAS同步操作的问题 ...

  4. Java并发(4)- synchronized与CAS

    引言 上一篇文章中我们说过,volatile通过lock指令保证了可见性.有序性以及"部分"原子性.但在大部分并发问题中,都需要保证操作的原子性,volatile并不具有该功能,这 ...

  5. Java并发编程总结2——慎用CAS(转)

    一.CAS和synchronized适用场景 1.对于资源竞争较少的情况,使用synchronized同步锁进行线程阻塞和唤醒切换以及用户态内核态间的切换操作额外浪费消耗cpu资源:而CAS基于硬件实 ...

  6. 浅析CompareAndSet(CAS)

    最近无意接触了AtomicInteger类compareAndSet(从JDK5开始),搜了搜相关资料,整理了一下 首先要说一下,AtomicInteger类compareAndSet通过原子操作实现 ...

  7. 多线程深入:乐观锁与悲观锁以及乐观锁的一种实现方式-CAS(转)

    原文:https://www.cnblogs.com/qjjazry/p/6581568.html 首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每 ...

  8. CAS适用场景

    转载:http://www.jb51.net/article/86192.htm 下面小编就为大家带来一篇Java并发编程总结——慎用CAS详解.小编觉得挺不错的, 现在就分享给大家,也给大家做个参考 ...

  9. Java并发问题--乐观锁与悲观锁以及乐观锁的一种实现方式-CAS

    首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁.传统的关系型数据库里边就用到了很 ...

随机推荐

  1. Java写的数据库连接池

    原文地址: http://lgscofield.iteye.com/blog/1820521 import java.sql.*; import java.util.Enumeration; impo ...

  2. 为什么JavaScript声明变量的时候鼓励加var关键字

    在JavaScript中,var用来声明变量,但是这个语法并不严格要求,很多时修改,我们可以直接使用一个变量而不用var声明它. var x = "XX"; y ="xx ...

  3. 天梯赛 L2-022. (数组模拟链表) 重排链表

    题目链接 题目描述 给定一个单链表 L1→L2→...→Ln-1→Ln,请编写程序将链表重新排列为 Ln→L1→Ln-1→L2→....例如:给定L为1→2→3→4→5→6,则输出应该为6→1→5→2 ...

  4. 在window 8 或windows2012 上用命令行安装framework3.5 方法

    找到对应操作系统安装目录的sources文件夹下的sxs文件夹,拷贝到本地电脑,如F:盘 根目录下 CMD(管理员身份)命令: dism.exe /online /enable-feature /fe ...

  5. 系统学习(javascript)_基础(数据类型一)

    五种基本数据类型:Number,String,Boolean,Null,Undefind: 三种引用数据类型:Object,Array,Symbol: Symbol为ECMAScript6新增的数据类 ...

  6. Spring Boot1.5X升级到2.0

    配置文件 大量的Servlet专属的server.* properties被移到了server.servlet下 拦截器 public class MyWebMvcConfigurerAdapter ...

  7. xss的一个tip

    其实可能不能算tip吧. 分享一下吧. unicode有四种编码方式 源文本:The &#x [Hex]:The &# [Decimal]:The \U [Hex]:\U0054\U0 ...

  8. getattr的使用

    from requests_html import HTMLSession class UrlGenerator(object): def __init__(self, root_url): self ...

  9. python 根据输入的内容输出类型

    类型判断 from functools import singledispatch import numbers from collections import abc from collection ...

  10. SQLAlchemy-介绍安装

    一:概述 SQLAlchemy的SQL工具包和对象关系映射是一个全面的工具集,用来处理数据库和Python. 它有几个不同的功能领域,可以单独使用或组合使用. 所示的主要组件,组件依赖关系组织成层: ...