锁这个词太有意思了,有几个意思?
读了第15章,大致感觉到了CAS的乐观锁特性。锁这个词太有意思了,有几个意思?
并发(多线程)编程的挑战之一就是解决对共享数据的竞争读写。各种Synchronizer的实现构成了解决这个问题的工具箱。
从更一般的、更笼统的意义上讲锁跟synchronizer其实一个意思,都可以看作是协调线程、控制线程的对象。这里所谓的更一般是说,我们可以把CountDownLatch、Semphore这些不带Locak字眼的Synchronizer也化分到锁这个概念里。
这样把概念统一到锁上之后,我们就可以把锁/Synchronizer分成耳熟能详的两类了:悲观锁、乐观锁。
对于乐观锁正如数据库事务解决方案里提到的乐观锁的概念,核心就是与观察旧值是否有变化而决定是否成功修改。
所以乐观锁想成基于“compare and set”的算法更好。更进一步把锁想成算法就好,具体的门锁那种感觉有点二狭隘了。
从最根本的提供“锁“算法实现的CPU指令上讲:对于乐观锁是CAS(LL, SC)提供了最核心的支持,对于悲观锁(对应到OS的互斥量,java的thread都一一映射到OS的thread)是lock指令前缀。除了这些CPU指令还有混存一致性协议这样的技术一起向上层提供了实现各种Syncrhonizer(悲观锁/乐观锁)的最基础支持。更详细内容可以参考文末的引用链接。
基于CAS实现的乐观锁其实不牵扯到什么类似mutex这样具体的锁,把它当作一种synchronizer就好(怎么有点儿金刚经的感觉)。我们可以利用CAS指令实现了非阻塞的多线程协调工作的各种算法。比如,列用CAS实现非阻塞计数器、非阻塞栈、非阻塞队列。JDK中的ConcurrentLinkedQueue就是利用原子化域更新器实现的支持并发(多线程)操作的非阻塞数据结构。
基于CAS cpu指令的有ABA问题。而load-linked/store-condition这样的cpu指令可以避免ABA问题。
从API的角度,可以用AtomicMarkableReference, AtomicStampedReference避免CAS下的ABA。
https://en.wikipedia.org/wiki/ABA_problem。
References:
《Java并发编程实践》
https://www.ibm.com/developerworks/cn/java/j-jtp04186/
0、https://blog.csdn.net/Saintyyu/article/details/94493694
1、https://blog.csdn.net/zacklin/article/details/7445442 原子操作与 x86 上的 lock 指令前缀
2、https://www.cnblogs.com/xrq730/p/7048693.html 就是要你懂Java中volatile关键字实现原理
3、https://blog.csdn.net/u011244446/article/details/52574369 Linux 互斥锁、原子操作实现原理
4、https://www.jianshu.com/p/6745203ae1fe 关于volatile、MESI、内存屏障、#Lock
5、https://www.jianshu.com/p/61490effab35 操作系统中锁的原理
6、https://www.cnblogs.com/XiaoHDeBlog/p/3740270.html Linux中同步互斥机制研究之原子操作
7、https://blog.csdn.net/Saintyyu/article/details/100838503 cas vs mutex