在同一个try块中锁定多个ReentrantReadWriteLocks是否安全? [英] Is it safe to lock multiple ReentrantReadWriteLocks in the same try block?

查看:167
本文介绍了在同一个try块中锁定多个ReentrantReadWriteLocks是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有两个资源,foo和bar。我使用一些 ReentrantReadWriteLock

Let's say I have two critial resources, foo and bar. I protect them with some ReentrantReadWriteLocks

ReentrantReadWriteLock foo = new RRWL() ...
ReentrantReadWriteLock bar = new RRWL() ...

大多数操作只使用foo OR bar,但其中一些恰好使用两者。现在当使用单个锁,你不能只这样做:

Most operations only use foo OR bar, but some of them happen to use both. Now when using a single lock, you can't just do this:

void foo() {
   foo.writeLock().lock();
   privateWorkOnFoo();
   foo.writeLock().unlock();
}

如果抛出异常,你的foo将永远锁定。

If an exception is thrown, your foo will become forever locked. Instead you wrap it, like

void foo() {
    try {
        foo.writeLock().lock();
        privateWorkOnFoo();
    } finally { foo.writeLock().unlock(); }
}

但是如果我需要同时工作呢?是否可以将它们放在一个块中?

But what if I need to work on both? Is it safe to put them in one block?

try {
    foo.writeLock().lock();
    bar.writeLock().lock();
    magic();
} finally { 
    bar.writeLock().unlock();
    foo.writeLock().unlock();
}

或者必须给每个锁定自己的块:

Or is it necessary to give each lock its own block:

try {
    foo.writeLock().lock();
    try {
        bar.writeLock().lock();
        magic();
    } finally { 
      bar.writeLock().unlock();
    }

} finally { 
    foo.writeLock().unlock();
}

我不能是第一个很难调查这个...我知道选项2有防弹,但它也是一个显着量更多的维护。是否可以接受选项1?

I can't have been the first person to have hard to investigate this before... I know option 2 there is "bulletproof" but it's also a significant amount more maintenance. Is option 1 acceptable?

推荐答案

选项1很好。它被称为两个锁变量。如果你看看LinkedBlockingQueue操作,如remove,它锁定putLock以及takeLock。这里有一个JDK的例子:

Option 1 is fine. It's known as the two lock variant. If you look at LinkedBlockingQueue operations such as remove, it locks the putLock as well as the takeLock. Here's a sample of what the JDK does:

  public boolean remove(Object o) {
       if (o == null) return false;
       fullyLock();
       try
       {
       // ...
       }   
       finally {
         fullyUnlock();
       }
    }

   /**
     * Lock to prevent both puts and takes.
     */
    void fullyLock() {
        putLock.lock();
        takeLock.lock();
    }

    /**
     * Unlock to allow both puts and takes.
     */
    void fullyUnlock() {
        takeLock.unlock();
        putLock.unlock();
    }

这篇关于在同一个try块中锁定多个ReentrantReadWriteLocks是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆