- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图理解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/
我有一个应用程序倾向于在后台线程中执行很多数据库 Activity (下载大型数据库更新),而且这个过程经常使“UI线程”匮乏-我知道数据库是不定期发布的,但是所使用的@synchronized机制不
我正在创建一个程序,用户可以在从一组项目中选择的两个项目之间进行一系列投票。每次投票后,会显示集合中的两个新项目并对其进行投票,直到看到集合中的所有成员。 这是我的限制条件: 每个用户应该以不同的随机
我正在开发一个在线判断类型的系统,其中大约 100 个不受信任的可执行文件将同时运行并评估相同的输入数据。 我希望每个可执行文件都限制在预定义资源池的 CPU、内存、磁盘空间等的相等份额。例如,如果资
我正在从事一个关于 CFS 的项目。使用Ftrace跟踪Linux公平进程的全路径。 根据文档 https://lwn.net/Articles/370423/ . [tracing]# echo $
Semaphore 类概述 developer.android.com看起来不错 - 对于那些已经熟悉这些概念和术语的人来说。 我熟悉那里的一些首字母缩略词和其他行话(例如 FIFO、锁等),但其他的
我是一名优秀的程序员,十分优秀!