gpt4 book ai didi

java - 理解java多线程中的公平锁

转载 作者:行者123 更新时间:2023-12-02 01:31:50 24 4
gpt4 key购买 nike

我试图理解java中的公平锁,并且我已经执行了一个实现

http://tutorials.jenkov.com/java-concurrency/starvation-and-fairness.html

效果很好

代码如下

public class FairLock 
{
private boolean isLocked = false;
private Thread lockingThread = null;
private List<QueueObject> waitingThreads =
new ArrayList<QueueObject>();

public void lock() throws InterruptedException
{
QueueObject queueObject = new QueueObject();
boolean isLockedForThisThread = true;
synchronized(this){waitingThreads.add(queueObject);}

while(isLockedForThisThread)
{
synchronized(this)
{
isLockedForThisThread =
isLocked || waitingThreads.get(0) != queueObject;
if(!isLockedForThisThread)
{
isLocked = true;
waitingThreads.remove(queueObject);
lockingThread = Thread.currentThread();
return;
}
}

try{queueObject.doWait();}
catch(InterruptedException e)
{
synchronized(this) { waitingThreads.remove(queueObject); }
throw e;
}
}
}

public synchronized void unlock()
{
if(this.lockingThread != Thread.currentThread())
{
throw new IllegalMonitorStateException(
"Calling thread has not locked this lock");
}

isLocked = false;
lockingThread = null;

if(waitingThreads.size() > 0){waitingThreads.get(0).doNotify();}
}
}

队列对象的代码

public class QueueObject 
{

private boolean isNotified = false;

public synchronized void doWait() throws InterruptedException
{
while(!isNotified){this.wait();}
this.isNotified = false;
}

public synchronized void doNotify()
{
this.isNotified = true;
this.notify();
}

public boolean equals(Object o){return this == o;}
}

我明白了大部分内容,但我有两个疑问

1)在这行代码中

   isLockedForThisThread =
isLocked || waitingThreads.get(0) != queueObject;

这部分的用途是什么?

waitingThreads.get(0) != queueObject;

它有什么作用?因为我删除了这部分代码,并且得到了相同的正确结果。

2)因为我相信我不需要那部分代码,所以我将 lock() 方法更改为下面给出的版本。

public void myLock() throws InterruptedException
{
QueueObject queueObject= new QueueObject();
synchronized(this){waitingThreads.add(queueObject);}

while(true)
{
synchronized(this)
{
if(!isLocked)
{
isLocked = true;
waitingThreads.remove(queueObject);
lockingThread = Thread.currentThread();
return;
}
}

try{queueObject.doWait();}
catch(InterruptedException e)
{
synchronized(this){waitingThreads.remove(queueObject);}
throw e;
}
}

这也给了我正确的结果,但我相信我还没有探索所有的情况,并且在某些情况下这会失败,我基本上需要专家的意见

.这会在哪里起作用?

.哪里会失败?

我是多线程新手,基本上是在寻找我的问题的一些解释(第 1 部分)和反馈(第 2 部分)

谢谢

最佳答案

注意这一行

synchronized(this){waitingThreads.add(queueObject);}

这里,我们将新创建的队列对象添加到队列中,但我们以同步方式执行此操作,因为 2 个线程可能会尝试同时将对象添加到列表中。考虑到这一点,让我们转到下一个同步块(synchronized block)

isLockedForThisThread =
isLocked || waitingThreads.get(0) != queueObject;

现在,如果其他线程正在运行,则该线程将被锁定,理想情况下将 isLocked 设置为 true,因此您的问题是为什么我们还要执行 waitingThreads.get(0) != queueObject。想象一下,在上一个 block 中,线程 A 在线程 B 之前将一个对象添加到队列中,这将使 A 优先运行,现在线程 A 可能会被挂起或发生其他情况,而线程 B 首先到达第二个同步块(synchronized block),让我们检查一下我们现在拥有的内容:1. isLocked 为 false,因为还没有线程将其设置为 true2. A 在队列中排在第一位,然后是 B3. 线程B正在运行,而线程A被挂起

现在,如果您执行您所做的操作并删除 || 的第二部分B 会认为轮到它来获取锁,并将进入下一个“if”语句,这不是正确的行为,因为下面的行将删除队列的第二个元素(在我们的示例中,它可能是第三个或在其他情况下甚至更多)而不是头元素。

waitingThreads.remove(queueObject);

无论如何,我都不是专家,但这就是我看到的问题,希望我有所帮助,仅使用文本来清楚地解释多线程行为可能很棘手:P

关于java - 理解java多线程中的公平锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55908266/

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