我遇到了Writer线程在没有获得锁的情况下被饥饿的问题。请看下面的代码。如果我试图使用读锁的tryLock()来获取锁,写进程将会变得饥饿,并且它将永远无法写入。即使在公平的情况下,编写器进程也会完全饿死,永远不会执行。相反,如果我只尝试reader.readLock(),那么写入器进程将能够获得锁。
请一定要让我知道,如果我错过了什么,写入器进程线程,即使它设置为高优先级,它永远不会获得锁,并将卡住等待锁。
谁能告诉我,我是否可以在ReadWriteLocks中使用trylock()。
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));
}
}发布于 2017-07-17 17:52:54
在这种情况下,如果不公平地使用ReentrantReadWriteLock,将永远不会起作用:太多的读取器线程只会使写入器线程饿死。
公平地说,编写器线程将偶尔获得写入的机会。
然而,在您的代码中将ReentrantReadWriteLock设置为fair是徒劳的。这里有个陷阱:你的读者使用的不是lock(),而是tryLock()。因此,它们永远不会排队等待锁获取,它们只是在锁可用时才会获得锁。并且通过不排队(在ReentrantReadWriteLock内部),它们绕过了公平策略。
注意ReadLock对象在tryLock()上的javadoc:
只有在调用时另一个线程没有持有写锁的情况下,
才会获取读锁。如果写锁未由另一个线程持有,则获取读锁,并立即返回值true。即使将此锁设置为使用公平排序策略,如果读锁可用,则对tryLock()的调用将立即获取读锁,而不管其他线程当前是否正在等待读锁。这种“插入”行为在某些情况下可能是有用的,即使它破坏了公平性。如果您希望遵守此锁的公平性设置,则使用几乎等效的tryLock(0,TimeUnit.SECONDS) (它还可以检测中断)。
如果写锁由另一个线程持有,则此方法将立即返回值false。
(强调我的)
https://stackoverflow.com/questions/45117061
复制相似问题