如果我有一个ReentrantReadWriteLock,并将它用作同步块中的锁,其他线程还能释放它们的锁吗?
例如:
ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
public void doSomething() {
synchronized(lock) {
lock.readLock().lock();
// do stuff
lock.readLock().unlock();
}
}如果我调用doSomething(),而另一个线程已经持有读锁,那么该线程能释放读锁吗?
当我进行doSomething()调用时,我将在ReentrantReadWriteLock上同步,然后尝试获取读锁。由于某些东西已经保存了读锁,我将阻塞直到该锁被释放。我很想知道读锁是否可以释放,因为我已经同步了锁本身。
发布于 2014-04-23 21:28:57
在ReentrantReadWriteLock对象上同步似乎是一个非常糟糕的主意。您的示例是锁定两个完全独立的锁。首先,它将内置到每个对象(在本例中为ReentrantReadWriteLock对象)的互斥锁锁定,然后锁定读取锁。
每当你看到一个锁时,你都应该问这个问题:“锁应该保护的不变量是什么?”这是另一种问:“如果锁不存在,您的数据会以什么方式被破坏?”
好的,synchronized(lock)保护什么?
那么,lock.readLock().lock()保护什么呢?
如果两个答案是相同的,那么为什么使用两个锁呢?
如果由我来决定的话,我一开始就不包括读/写锁
您不妨将您的示例更改为:
Object lock = new Object();
public void doSomething() {
synchronized(lock) {
// do stuff
}就您向我们展示的代码而言,它的行为不会有任何不同。(尽管如此,它可能会改变您的示例与您尚未向我们展示的其他代码的交互方式。)
发布于 2014-04-23 21:40:37
编写一个示例非常简单,该示例显示一个在实际锁对象上保存监视器的线程不会阻碍其他线程获取和释放读锁。(当然,这并没有被实际记录下来,所以在理论上,对于另一个Java实现来说可能是不同的!)
public static void main(String[] args) throws Exception {
final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
synchronized (lock) {
lock.readLock().lock();
try {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
lock.readLock().lock();
try {
System.out.println("foo");
} finally {
lock.readLock().unlock();
}
}
}).start();
}
Thread.sleep(500);
System.out.println("done");
} finally {
lock.readLock().unlock();
}
}
}https://stackoverflow.com/questions/23255083
复制相似问题