Java 可重入写回和同步块
如果我有一个Java 可重入写回和同步块,java,multithreading,synchronization,locking,Java,Multithreading,Synchronization,Locking,如果我有一个ReentrantReadWriteLock,并且我使用它作为同步块中的锁,那么其他线程仍然可以释放它们的锁吗 例如: ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); public void doSomething() { synchronized(lock) { lock.readLock().lock(); // do stuff lock.r
ReentrantReadWriteLock
,并且我使用它作为同步块中的锁,那么其他线程仍然可以释放它们的锁吗
例如:
ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
public void doSomething() {
synchronized(lock) {
lock.readLock().lock();
// do stuff
lock.readLock().unlock();
}
}
如果我调用doSomething()
而另一个线程已经持有读锁,该线程可以释放读锁吗
当我调用
doSomething()
时,我将在ReentrantReadWriteLock
上进行同步,然后尝试获取读锁。因为有东西已经持有读锁,我将阻止,直到该锁被释放。我很想知道读锁是否可以释放,因为我已经在锁本身上进行了同步。在可重入的TreadWriteLock对象上同步似乎是一个非常糟糕的主意。您的示例是锁定两个完全独立的锁。首先,它锁定每个对象(在本例中为ReentrantReadWriteLock对象)中内置的互斥锁,然后锁定读锁
每当您看到锁时,都应该问这样一个问题,“锁应该保护的不变量是什么?”这是另一种提问方式,“如果没有锁,您的数据会以什么方式被破坏?”
好的,同步(锁定)
保护什么
还有,lock.readLock().lock()
保护什么
如果两个答案相同,那么为什么要使用两个锁呢
如果由我决定的话,我甚至不会在一开始就包含读/写锁
您不妨将示例更改为:
Object lock = new Object();
public void doSomething() {
synchronized(lock) {
// do stuff
}
就您向我们展示的代码而言,它的行为不会有任何不同。(不过,它可能会改变您的示例与您没有向我们展示的其他代码的交互方式。)编写一个示例来说明一个线程在实际锁对象上持有监视器不会妨碍其他线程获取和释放读锁,这是相当简单的。(这当然没有实际的文档记录,因此对于另一种Java实现,理论上可能会有所不同!)
publicstaticvoidmain(字符串[]args)引发异常{
最终ReentrantReadWriteLock锁=新的ReentrantReadWriteLock(真);
已同步(锁定){
lock.readLock().lock();
试一试{
对于(int i=0;i<10;i++){
新线程(newrunnable()){
@凌驾
公开募捐{
lock.readLock().lock();
试一试{
System.out.println(“foo”);
}最后{
lock.readLock().unlock();
}
}
}).start();
}
睡眠(500);
系统输出打印项次(“完成”);
}最后{
lock.readLock().unlock();
}
}
}
uuh,既然一开始就使用锁,为什么要同步??另外,您应该在块前面锁定,然后在块中解锁,最后解锁它的现有代码。我正试图找出僵局的根源。我原本以为这是一个问题,但有三个线程涉及。如果由我决定的话,我甚至不会把读写锁放在第一位。我不知道你的确切问题是什么。但是多个线程可以获取lock.readLock()
。关于这段代码…我认为是“过度同步”(如果这个词evenn存在:)并且在我看来使用错误。当您删除同步块代码时,也会导致写入锁。但我认为在示例中只使用一种锁类型会更简单。
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();
}
}
}