CAS
CAS(轻量级锁),使用atomic类的原子操作方法实现。调用方法传入预期值和更改值,如果预期值和老值相等,替换为新值(加锁成功),否则返回false。
CAS原子性问题:
比较交换是多个语句,CPU自动保证一个缓存行操作的原子性。如果超过一个缓存行,就会加总线锁来实现原子性。
CAS ABA问题:
线程1拿到预期值,线程2执行快,把值改变了,又改为原来的值,线程1比较发现是原来的值(本质变了)。通过加版本号,比较值相同在比较版本号。
CAS自旋占用CPU,如果线程多可能不如重量级锁进入等待队列的方式。
偏向锁:多个线程同时去争抢一把锁的时候很少,通常是一个线程执行代码,把线程id存入锁对象中(存在对象头markword中),判断是当前线程就不需要枷锁,直接执行代码。
对象头的对齐填充的作用:JVM规定(JVM寻址最优方式),对象大小要被8整除,如果不能会补齐空白至对齐填充区。
synchronize
synchronize通过进入和退出对象的monitor监视器锁实现,底层使用操作系统互斥锁,重量级锁,消耗大。在JDK1.6之后对synchronize关键字进行优化,加入了锁膨胀升级机制,开始是无锁状态,一个线程访问时升级为偏向锁,多个线程发生竞争时升级为轻量级锁,自旋一定次数后(默认十次)还没抢到锁就会升级为重量级锁。锁升级的过程是不可逆的,通过对象头的mark word来标记锁状态和记录偏向锁偏向的线程。
Longadder
分段CAS,有一个Base值,和一个CELL数组,多个线程做++,对每个线程分配一个新的CELL对象(数组的值,CELL1,CELL2),让线程对CELL值做CAS比较。最后在做求和。