StampedLock锁

StampedLock 支持的三种锁模式  写锁、悲观读锁和乐观读
我们先来看看在使用上 StampedLock 和上一篇文章讲的 ReadWriteLock 有哪些区别。ReadWriteLock 支持两种模式:一种是读锁,一种是写锁。而 StampedLock 支持三种模式。其中写锁、悲观读锁的语义和 ReadWriteLock 的写锁、读锁的语义非常类似,允许多个线程同时获取悲观读锁,但是只允许一个线程获取写锁,写锁和悲观读锁是互斥的。不同的是:StampedLock 里的写锁和悲观读锁加锁成功之后,都会返回一个stamp;然后解锁的时候,需要传入这个 stamp。相关的示例代码如下。
final StampedLock sl =  new StampedLock();

    // 获取 / 释放悲观读锁
    long stamp = sl.readLock();
    try {
     // 省略业务相关代码.....
      } finally {
        sl.unlockRead(stamp);
    }

    // 获取 释放写锁
    long stamp = sl.writeLock();
    try {
        // 省略业务相关代码.....
    } finally {
        sl.unlockWrite(stamp);
    }
 
StampedLock 的性能之所以比 ReadWriteLock 还要好,其关键是 StampedLock 支持乐观读的方式。ReadWriteLock 支持多个线程同时读,但是当多个线程同时读的时候,所有的写操作会被阻塞;而 StampedLock 提供的乐观读,是允许一个线程获取写锁的,也就是说不是所有的写操作都被阻塞。注意这里,我们 用的是“乐观读”这个词,而不是“乐观读锁”,是要提醒你,乐观读这个操作是无锁的,所以相比较 ReadWriteLock 的读锁,乐观读的性能更好一些。
 

 

在上面这个代码示例中,如果执行乐观读操作的期间,存在写操作,会把乐观读升级为悲观读锁。这个做法挺合理的,否则你就需要在一个循环里反复执行乐观读,直到执行乐观读操作的期间没有写操作(只有这样才能保证 x 和 y 的正确性和一致性),而循环读会浪费大量的 CPU。升级为悲观读锁,代码简练且不易出错,建议你在具体实践时也采用这样的方法。

文中部分来源:王宝令 《StampedLock:有没有比读写锁更快的锁》

 
 

猜你喜欢

转载自www.cnblogs.com/amberJava/p/12364602.html