[英]ReentrantReadWriteLock and synchronized blocks
如果我有一個ReentrantReadWriteLock
,並且將它用作同步塊中的鎖,其他線程是否還能釋放它們的鎖?
例如:
ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
public void doSomething() {
synchronized(lock) {
lock.readLock().lock();
// do stuff
lock.readLock().unlock();
}
}
如果我調用doSomething()
並且另一個線程已經持有讀取鎖,那么該線程可以釋放讀取鎖嗎?
調用doSomething()
時,我將在ReentrantReadWriteLock
上進行同步,然后嘗試獲取讀取鎖。 由於某些東西已經持有讀取鎖,因此我將阻塞直到釋放該鎖。 我很想知道是否可以釋放讀取鎖,因為我已經同步了鎖本身。
在ReentrantReadWriteLock對象上同步似乎是一個非常糟糕的主意。 您的示例是鎖定兩個完全獨立的鎖。 首先,它鎖定內置到每個對象(在本例中為ReentrantReadWriteLock對象)中的互斥鎖,然后鎖定讀取鎖。
每當您看到鎖時,都應該問這個問題:“鎖應該保護什么不變性?” 這是另一種詢問方式:“如果沒有鎖,您的數據將以何種方式被破壞?”
好, synchronized(lock)
保護什么?
而且, lock.readLock().lock()
保護?
如果兩個答案都相同,那么為什么要使用兩個鎖?
如果由我決定,那么我什至不包括讀/寫鎖定
您最好將示例更改為此:
Object lock = new Object();
public void doSomething() {
synchronized(lock) {
// do stuff
}
就您向我們展示的代碼而言,它的行為沒有任何不同。 (盡管如此,它可能會改變您的示例與未顯示給我們的其他代碼交互的方式。)
編寫一個示例,表明一個將監視器保持在實際鎖對象上的線程不會阻礙其他線程獲取和釋放讀取鎖,這是相當瑣碎的。 (這當然沒有實際記錄,因此在理論上對於備用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();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.