gpt4 book ai didi

java - 当 writeLock 锁定时,ReentrantReadWriteLock 是否会读取?

转载 作者:太空宇宙 更新时间:2023-11-04 14:56:57 26 4
gpt4 key购买 nike

我研究了ReentrantReadWriteLock

我编写了简单的测试代码(我知道使用 Thread.sleep() 不能保证可预测的结果,但我认为我很幸运:)):

public class RWLock {
private static String val = "old";
private static ReadWriteLock lock = new ReentrantReadWriteLock();
private static long time = System.currentTimeMillis();
public void read() {
try {
lock.readLock().lock();
System.out.println("read " + val +" - "+(System.currentTimeMillis()-time));
Thread.sleep(300);
} catch (InterruptedException e) {

} finally {
lock.readLock().unlock();
}
}

public void write() {
try {
lock.writeLock().lock();
val = "new";
System.out.println("write " + val+" - "+(System.currentTimeMillis()-time));
Thread.sleep(10000);
} catch (InterruptedException e) {

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

class Tester {
public static void main(String[] args) throws InterruptedException {

new MyThreadRead().start();

Thread.sleep(400);
new MyThreadWrite().start();
}

}

class MyThreadRead extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
new RWLock().read();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
}

class MyThreadWrite extends Thread {
@Override
public void run() {
new RWLock().write();
}
}

输出:

read old - 0
write new - 401
read new - 10401
read new - 10902
read new - 11402
read new - 11902
read new - 12402
read new - 12902
read new - 13402
read new - 13902
read new - 14402

10401 - 401 == 10000

10000 现在是写作时间。

据我了解,第二个读取线程无法在写入之前完成。因此写入和二次读取是并行执行的。这对我来说不是可预测的行为。

你对此有何看法?

最佳答案

也许您的 sleep() 调用比您意识到的要多。 MyThreadRead#run() 和 RWLock()#read() 中的 sleep 调用总计达 500 毫秒。所以这就是发生的事情。

At T=0, the reader thread grabs the read lock and sleeps for 300ms.
At T=300, the reader releases the lock, and then sleeps for another 200ms.
At T=400, the writer grabs the write lock and sleeps for ten seconds,
At T=500, the reader tries to grab the read lock, but it is blocked by the writer.
At T=10400, the writer gives up the lock, and then the reader gets to go round
its loop nine more times.
<小时/>

P.S.:将 lock() 调用移出 try/finally 语句。例如,

...lock()
try {
...
} finally {
...unlock();
}

这样,如果lock()调用抛出异常,则unlock()将不会被调用。

关于java - 当 writeLock 锁定时,ReentrantReadWriteLock 是否会读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23093581/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com