- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是某种 Java 谜题,我偶然发现但无法真正解释。也许有人可以?
以下程序在短时间内挂起。有时在 2 个输出之后,有时在 80 个输出之后,但几乎总是在正确终止之前。如果第一次没有发生,您可能需要运行几次。
public class Main {
public static void main(String[] args) {
final WorkerThread[] threads = new WorkerThread[]{ new WorkerThread("Ping!"), new WorkerThread("Pong!") };
threads[0].start();
threads[1].start();
Runnable work = new Runnable() {
private int counter = 0;
public void run() {
System.out.println(counter + " : " + Thread.currentThread().getName());
threads[counter++ % 2].setWork(this);
if (counter == 100) {
System.exit(1);
}
}
};
work.run();
}
}
class WorkerThread extends Thread {
private Runnable workToDo;
public WorkerThread(String name) {
super(name);
}
@Override
public void run() {
while (true){
if (workToDo != null) {
workToDo.run();
workToDo = null;
}
}
}
public void setWork(Runnable newWork) {
this.workToDo = newWork;
}
}
现在,很明显,繁忙的等待循环一般来说并不是一个好主意。但这不是为了改进,而是为了了解正在发生的事情。
因为当 WorkerThread.setWork()
已synchronized
或当 WorkerThread.workToDo
字段设置为 时,一切都会按预期工作 volatile
我怀疑内存有问题。
但到底为什么会发生这种情况呢?调试没有帮助,一旦开始单步执行,一切都会按预期运行。
如有解释,我们将不胜感激。
最佳答案
第一个问题是您从 main
线程设置 Runnable workToDo
,然后在 2 个 fork 线程中读取它而不进行同步。每当您在多个线程中修改字段时,都应将其标记为 volatile
或某人同步
。
private volatile Runnable workToDo;
此外,由于多个线程正在执行 counter++
,因此也需要同步
。为此,我推荐使用 AtomicInteger
。
private AtomicInteger counter = new AtomicInteger(0);
...
threads[counter.incrementAndGet() % 2].setWork(this);
但我认为真正的问题可能是竞争条件之一。两个线程都可以将 workToDo
设置为 Runnable
,然后让它们都返回并将其设置回 null
,以便它们将会永远旋转。我不知道如何解决这个问题。
1. threads[0] has it's `workToDo` set to the runnable. It calls `run()`.
2. at the same time threads[1] also calls `run()`.
3. threads[0] sets the `workToDo` on itself and threads[1] to be the runnable.
4. at the same time threads[1] does the same thing.
5. threads[0] returns from the `run()` method and sets `workToDo` to be `null`.
6. threads[1] returns from the `run()` method and sets `workToDo` to be `null`.
7. They spin forever...
而且,正如您提到的,旋转循环很疯狂,但我认为这是一个演示线程程序。
关于Java谜题: busy wait threads stop working,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16179525/
我经常使用stop Fortran 中固有的因各种原因停止执行(主要是在测试失败后)。 program test1 stop end program 除了停止程序执行之外什么都不做。 prog
我想编写一个函数,用字符 e 替换所有出现的字符 c。这些功能似乎正在发挥作用。然而,主要是,我希望能够重复输入一个字符串,扫描要替换的字符,扫描要替换的字符,并打印之前和之后的内容,直到输入的字符串
在 powershell 中,我看到了多种停止服务的方法 更现代的方式 Stop-Service wuauserv 而更传统的方式 NET STOP WUAUSERV 遗留方式 is much mor
所以问题是我需要一个正则表达式,只有当它的 stop 也意味着 stopp 或 sstoooppp 时,它才会匹配第二个单词> 后跟一个空格。我需要得到这个词,我找不到任何正则表达式来做到这一点,因为
我正在做这样的事情 http://jsfiddle.net/8ErSL/2/ 当您将鼠标悬停在任何文本框 (div) 上时,其中会出现一个小图标。 我想阻止图标的淡入淡出效果在我不小心将鼠标悬停在 d
这段代码在 Debug模式下工作得很好,但当不是 Debug模式时它总是抛出运行时异常。 mMediaRecorder.stop(); 根据 Java 文档: Stops recordin
这是我的full code ,这里是my project ,当我在 #onCreate 中使用 MediaRecorder#stop 时,它会引发 java.lang.RuntimeException
我使用 C# 编写了一个库并在 PowerShell 脚本中使用它。 C# 库将大量数据加载到数据库中。我正在使用 Start-Job 来启动该过程,并且我正在监视一个文件是否有错误。 但是,我发现即
我正在尝试编写以下问题的代码: 在 a0, a1, ..., an 处有 n 个酒店,使得 0 dp(k)+(ai-ak)^2) dp(i) = dp(k)+(ai-ak)^2)
我有一个简单的测试,我使用 run_forever 方法运行 Python asyncio 事件循环,然后立即在另一个线程中停止它。但是,事件循环似乎并没有终止。我有以下测试用例: import as
我有以下情况: 专用租赁 m4.large 运行 RHEL6 的 EC2 实例 使用 AWS 控制台手动启动它效果很好 尝试启动它的 Lambda 函数(用 Java 编写)失败,因为实例状态为:已停
我正在使用 Yajsw 将我的应用程序作为守护进程运行。 对于状态调用,我希望看到“正在运行”或“已停止”,但我收到的消息如下所示 SW043305-SRV01:/etc/init.d # ./tes
在 Tomcat 或 TomEE 中,service tomcat start/stop 和 ./catalina.sh run/stop 有什么区别? 他们做的事情完全一样吗? 最佳答案 catal
我正在尝试使用 C++ 和 OpenGL/GLUT 制作一个 Snake 克隆。然而,我一直在编程允许输入 Action 之间的短时间间隔时遇到问题。我已经尝试了一些计时方法,最后我为它创建了一个类(
问题: org.apache.catalina.loader.WebappClassLoader - The web application [/…] appears to have started
我正在尝试以下实验: 我有两个QpushButtons,比如PushA 和PushB。现在 PushA 在 QHBoxLayout 中,PushB 也在它自己的 QHBoxLayout 中。这两个水平
我已经在我的 windows 10 机器上安装了 Docker for Windows。当我尝试从“windows 容器”“切换到 linux 容器”时,出现错误。 Unable to start:
我在我的应用程序中集成了摄像头。当用户单击捕获按钮时,我隐藏了工具栏,以便摄像头预览屏幕尺寸增加。这会导致应用程序在停止在线录制时崩溃 - mMediaRecorder.stop(); 。 java.
运行功能时 stop("m Sys.setenv(LANG = "fr") > 2 + x Erreur : objet 'x' introuvable > Sys.setenv(LANG = "en
我有一个 Windows 10 内部版本,我正在尝试安装 cpriego/valet-linux使用 wsl2 我已经安装了 composer、php 和所有其他的要求。 现在当我做 valet st
我是一名优秀的程序员,十分优秀!