作者回复: 回答很全面
作者回复: 第一个问题,这里有一个公平锁和非公平锁的情况,如果是公平锁,即使无锁竞争的情况下,也会进入阻塞队列中排队获取锁;否则,会立即CAS获取到读锁。
第二个问题,是公用的,这里同样涉及到了公平锁和非公平锁,读写线程对于程序来说都是一样的。如果是非公平锁,如果没有锁竞争的情况下CAS获取锁成功,是无需进入阻塞队列。如果是公平锁,都会进入阻塞队列。
作者回复: 是的,StampedLock不支持可重入。如果在一些需要重入的代码中使用StampedLock,会导致死锁、饿死等情况出现。
作者回复: 可重入锁是指在同一个线程在前面方法中已获取锁了,再进入该线程的其他方法获取锁,此时不会因为之前获取锁而阻塞。
平时我们很少遇到这种情况,例如在A方法中使用了对象锁,B方法中也使用了该对象锁,平时一般都是分别调用A方法和B方法,而后面由于业务需求刚好需要在A方法中调用B方法,此时就会需要锁支持可重入性。
作者回复: 是的,写多读少的性能没有优势。
作者回复: 第一个问题,是老师笔误,搞错方向了,现在已更正。
第二个问题,如果读多写少的情况下,即使是公平锁,也是需要长时间等待,不是想获取时就能立即获取到锁。StampedLock如果是处于乐观读时,写锁是可以随时获取到锁。
第三个问题,StampedLock源码中存在大量compareAndSwapObject操作来保证原子性。
作者回复: 这就是一种按版本号实现的读乐观锁,我们经常会在数据库更新操作时用到这种基于版本号实现的写乐观锁。
对的,StampedLock不支持重入。
作者回复: 是的
作者回复: lock锁阻塞不会带来进程间的上下文切换,IO流存在的,在09讲中讲到了
作者回复: 从源码分析,都会进行高低位的判断,获取写锁时,如果state!=0 and w==0,就可以判断了此锁r!=0,也就是判断了高16位有没有读锁了。
作者回复: 一般占有锁时间非常短,队列的长度也不会太长,这个性能几乎可以忽略
作者回复: 我们进入到底层代码,可以发现其实公平锁和非公平锁的区别就是是否进入队列,公平锁是会进入到队列中排队等待唤醒,而非公平锁则是直接CAS获取锁。
Lock锁如果监测到中断就直接throw new InterruptedException();抛出来了,所以可以响应中断。
具体可参考源码。
作者回复: 对的