首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ReadWriteLock写锁饱和

ReadWriteLock写锁饱和
EN

Stack Overflow用户
提问于 2017-07-15 18:18:47
回答 1查看 448关注 0票数 0

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

请一定要让我知道,如果我错过了什么,写入器进程线程,即使它设置为高优先级,它永远不会获得锁,并将卡住等待锁。

谁能告诉我,我是否可以在ReadWriteLocks中使用trylock()

代码语言:javascript
复制
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));

    }
}
EN

回答 1

Stack Overflow用户

发布于 2017-07-17 17:52:54

在这种情况下,如果不公平地使用ReentrantReadWriteLock,将永远不会起作用:太多的读取器线程只会使写入器线程饿死。

公平地说,编写器线程将偶尔获得写入的机会。

然而,在您的代码中将ReentrantReadWriteLock设置为fair是徒劳的。这里有个陷阱:你的读者使用的不是lock(),而是tryLock()。因此,它们永远不会排队等待锁获取,它们只是在锁可用时才会获得锁。并且通过不排队(在ReentrantReadWriteLock内部),它们绕过了公平策略。

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

只有在调用时另一个线程没有持有写锁的情况下,

才会获取读锁。如果写锁未由另一个线程持有,则获取读锁,并立即返回值true。即使将此锁设置为使用公平排序策略,如果读锁可用,则对tryLock()的调用将立即获取读锁,而不管其他线程当前是否正在等待读锁。这种“插入”行为在某些情况下可能是有用的,即使它破坏了公平性。如果您希望遵守此锁的公平性设置,则使用几乎等效的tryLock(0,TimeUnit.SECONDS) (它还可以检测中断)。

如果写锁由另一个线程持有,则此方法将立即返回值false。

(强调我的)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45117061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档