我试图了解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部分中)
谢谢
答案 0 :(得分:2)
注意此行
synchronized(this){waitingThreads.add(queueObject);}
在这里,我们将新创建的队列对象添加到队列中,但是我们以同步的方式进行操作,因为两个线程可能试图同时将一个对象添加到列表中。考虑到这一点,让我们转到下一个同步块
isLockedForThisThread =
isLocked || waitingThreads.get(0) != queueObject;
现在,如果正在运行其他线程(最好将isLocked设置为true),则该线程将被锁定,因此您的问题是为什么我们还要执行waitingThreads.get(0)!= queueObject。想象一下,在前一个块中,线程A在线程B之前将对象添加到队列中,它是拥有的,这将赋予A首先运行的优先级,现在线程A可能挂起或某些东西,线程B首先到达第二个同步块,让我们检查一下我们现在拥有的: 1. isLocked为false,因为还没有线程将其设置为true 2. A在队列中排在首位,然后是B 3.在线程A挂起的同时线程B正在运行
现在,如果您执行了操作,则删除了||的第二部分。 B将认为轮到该锁定并进入下一个'if'语句,这不是正确的行为,因为下一行将删除队列的第二个元素(在我们的示例中,它可能是在其他情况下为3甚至更高),而不是head元素。
waitingThreads.remove(queueObject);
我绝对不是专家,但这是我看到的问题,希望我能帮助仅使用文本来清楚地解释多线程行为可能很棘手。