Java并发 CAS AQS
前言:
摒弃segment利用CAS算法,底层依然对数组+链表+红黑树 不离不弃,为了并发、添加了些对象内部类
CAS:CompareAndSwap
乐观锁的宝贝甜蜜饯
比较并替换,3个操作数:内存地址V 、旧的预期值A 、要更新的目标值B:当且仅当V==A才V=B
CPU硬件指令保证:JNI(Java Native Interface)调用native方法(c++硬件级指令)jdk提供unsafe类执行
Unsafe
类是CAS实现的核心,封装了一些类似于C++中指针的东西,类中的方法都是native、原子
compareAndSwapInt、Atomic::cmpxchg、lock前缀 :CAS"自旋"
Java并发包原子操作类(Atomic开头)AtomicInteger借助C来调用CPU底层指令
lock前缀
单处理器没有必要加lock前缀,多核情况下添加lock
1、确保对内存读-改-写原子执行,锁定单个缓存行中的内存区域:缓存锁定(原则性)多处理器锁住总线:CAS原子操作
2、写缓冲区中all数据刷新到内存中,禁止该指令与前后的读写指令重排序:内存屏障效果:volatile读写的内存语义
缺点:
1、失败重试循环时间长开销大:如jvm支持pause(延迟流水线执行指令、不耗more执行资源;避免退循环时内存顺序冲突而引起cpu流水线被清空,提供cpu执行效率);
2、只保证一个共享变量的原子操作,多个用锁或Java1.5用AtomicReference类保证引用对象间的原子性,可把多个变量放在一个对象里来进行CAS操作;
3、ABA a改成b再改成a +标记:互斥同步
ABA
JAVA1.5提供AtomicStampedReference解决,compareAndSet首先检查当前引用是否等于预期引用,并当前标志是否等于预期标志,如全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值
Java中
1、处理器上提供的高效机器级别原子指令以原子方式对内存读-改-写
2、volatile变量的读/写和CAS可以实现线程之间的通信——合作:整个concurrent包实现的基石
实现模式:
声明共享变量为volatile
使用CAS的原子条件更新来实现线程之间的同步
配合以volatile的读/写和CAS所具有的volatile读和写的内存语义来实现线程之间的通信
队列:
同步队列:存放着 竞争同步资源的线程 的引用
线程获取同步状态失败,同步器会将当期线程及等待状态的等信息构造成为一个节点并将其加入同步队列,首节点表示获取同步状态成功的线程节点
等待队列:存放着 等待唤醒的线程 的引用
AQS:AbstractQueuedSynchronizer
抽象的队列式的同步器,多线程访问共享资源的同步器框架
两种共享资源的方式:
Exclusive(独占,只有一个线程能执行,如ReentrantLock)
Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)
https://www.cnblogs.com/waterystone/p/4920797.html
https://blog.csdn.net/Hsuxu/article/details/9467651
https://blog.csdn.net/pi9nc/article/details/39177343
https://www.cnblogs.com/dongguacai/p/5984827.html
https://blog.csdn.net/liubenlong007/article/details/53761730
https://blog.csdn.net/MakeContral/article/details/78135531?locationNum=5&fps=1队列