gpt4 book ai didi

java - ReadWriteLock 写锁饱和

转载 作者:行者123 更新时间:2023-12-02 12:36:56 25 4
gpt4 key购买 nike

我遇到了 Writer 线程在没有获得锁的情况下饥饿的问题。请看下面的代码。如果我尝试使用 tryLock() 获取读锁,写入进程将变得饥饿,并且永远无法写入。即使具有公平性,编写过程也会完全饥饿并且永远不会执行。相反,如果我只尝试reader.readLock(),那么写入进程将能够获得锁。

如果我遗漏了某些内容,请告诉我,即使写入进程线程设置为高优先级,它也永远不会获得锁,并且会卡在等待锁的过程中。

谁能告诉我是否可以将 trylock()ReadWriteLocks 一起使用。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.*;

class ReadWrite{
private int a, j=0,k =0;

private final ReentrantReadWriteLock asd = new ReentrantReadWriteLock();
private final Lock readlock = asd.readLock();
private final Lock writelock = asd.writeLock();
ReadWrite(){
a = 0 ;
}
ReadWrite(int a){
this.a = a;
}
public int read() {

try {
if (readlock.tryLock())
{
//readlock.lock();

k = k + 1;
if (k%100000==0) {
System.out.println("read " + k + " times ==> Written " + j + " times");

}

readlock.unlock();

return a;
}



}
catch(Exception E) {
System.out.println(E);
return a;
}
return 0;

}
public void write(int a) {
int k = 9;
try {
writelock.lock();
//writelock.lock();
this.a = a;
k = 0;
j = j + 1;
System.out.println("Acquored");
}
catch(Exception E) {
System.out.println(E);
}
finally {
if (k == 0 )
writelock.unlock();
}
}

}

class reader implements Runnable{
ReadWrite a;
reader(Object b){
a = (ReadWrite) b;
}
public void run() {
while(true) {

try{a.read();
//Thread.sleep(100);
}
catch(Exception E) {

}
}
}
}
class writer implements Runnable{
ReadWrite a;
writer(Object b){
a = (ReadWrite) b;
}
public void run() {
//Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
while(true) {
try {
//Thread.sleep(1);
}
catch(Exception E) {

}
a.write((int) Math.ceil(Math.random()*100));
}
}
}
class Practice{
public static void main(String args[]) {
ReadWrite a = new ReadWrite();
System.out.println("Invoking Write Thread");
ExecutorService asd = Executors.newFixedThreadPool(100);
asd.execute(new writer(a));

for (int i = 0 ; i < 98 ; i ++)
asd.execute(new reader(a));

}
}

最佳答案

在这种不公平的情况下使用ReentrantReadWriteLock永远不会起作用:太多的读取器线程只会让写入器线程挨饿。

公平地说,作者线程偶尔会有写作的机会。

然而,在代码中将ReentrantReadWriteLock设置为公平被证明是徒劳的。问题是:你的读者不使用 lock(),而是使用 tryLock()。因此,它们永远不会排队等待锁获取,它们只是在可用时获取它。并且通过不排队(在ReentrantReadWriteLock内部),它们规避了公平策略。

请注意 ReadLock 对象的 tryLock() 上的 javadoc:

Acquires the read lock only if the write lock is not held by another thread at the time of invocation. Acquires the read lock if the write lock is not held by another thread and returns immediately with the value true. Even when this lock has been set to use a fair ordering policy, a call to tryLock() will immediately acquire the read lock if it is available, whether or not other threads are currently waiting for the read lock. This "barging" behavior can be useful in certain circumstances, even though it breaks fairness. If you want to honor the fairness setting for this lock, then use tryLock(0, TimeUnit.SECONDS) which is almost equivalent (it also detects interruption).

If the write lock is held by another thread then this method will return immediately with the value false.

(强调我的)

关于java - ReadWriteLock 写锁饱和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45117061/

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