在使用ReentrantReadWriteLock时,关于锁降级的一点疑问?

发布于 2022-09-06 20:05:44 字数 1241 浏览 16 评论 0

在查看ReentrantReadWriteLock的官方文档中看到了一个关于锁降级的例子代码:

 class CachedData {
   Object data;
   volatile boolean cacheValid;
   final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

   void processCachedData() {
     rwl.readLock().lock();
     if (!cacheValid) {
       // Must release read lock before acquiring write lock
       rwl.readLock().unlock();
       rwl.writeLock().lock();
       try {
         // Recheck state because another thread might have
         // acquired write lock and changed state before we did.
         if (!cacheValid) {
           data = ...
           cacheValid = true;
         }
         // Downgrade by acquiring read lock before releasing write lock
         rwl.readLock().lock();
       } finally {
         rwl.writeLock().unlock(); // Unlock write, still hold read
       }
     }

     try {
       use(data);
     } finally {
       rwl.readLock().unlock();
     }
   }
 }

这里,在释放写锁前需要先申请读锁,也既锁降级。具体原因是,如果不先获取读锁就释放写锁,那么在执行后面的use(data)时,data有可能被其它线程修改。而由于一个线程对于共享变量的修改对另一个线程来说是不可见的,所以会导致错误。这里,请问,如果我把data变量用volatile修饰,通过volatile来保证可见性的话,是否还需要使用锁降级呢?不知道我对于volatile保证可见性的理解是否正确?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

∞琼窗梦回ˉ 2022-09-13 20:05:44

这里锁释放时,会把data刷会共享内存及主内存的。不存在可见性了吧 锁降级的主要目的应该还是在逻辑上。我觉得因为写读互斥,所以我们一直持有写锁的话,其他线程就无法读了,所以

柳絮泡泡 2022-09-13 20:05:44

我根本无法理解为什么要降级,你用写锁更新完了数据,别的线程同样需要进行写操作,自然锁释放后即可拿到,你又套了个读锁的意义在哪?。。。业务上有没有具体应用呢?

最初的梦 2022-09-13 20:05:44

他这里说的不可见是说在同一个线程中是没法感知其它线程对该变量进行的修改。
user(data),在当前线程中data为1,而在其他线程中被修改为2。虽然你通过增加volatile让当前线程知道了data被修改为2,但从程
序逻辑中你是没法判断它有没有被修改过,are you understand?锁降级的目的是保证在同一线程中数据的感知性,我觉得这里用可见性表达不准确。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文