Java – is it safe to lock multiple reentrantreadwritelocks in the same try block?

Suppose I have two key resources, Foo and bar I protected them with some reentrantreadwritelock

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

Most operations use only 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();
}

If you throw an exception, your foo will be locked forever Instead, you wrap it up, like

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

But what if I need to work at the same time? Is it safe to put them in one block?

Option 1

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

Or is it necessary to provide each lock with its own block:

Option 2

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

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

I can't be the first person to investigate this... I know option 2 has "bulletproof", but it's also a considerable amount of maintenance Is option 1 acceptable?

Solution

Option 1 is OK It is called two locking variants If you look at the linkedblockingqueue operation, such as remove, it will lock putlock and takelock The following is a functional example of JDK:

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();
    }
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>