public class GuardedBlock {
private boolean guard = false;
private static void threadMessage(String message) {
System.out.println(Thread.currentThread().getName() + ": " + message);
}
public static void main(String[] args) {
GuardedBlock guardedBlock = new GuardedBlock();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
guardedBlock.guard = true;
threadMessage("Set guard=true");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
threadMessage("Start waiting");
while (!guardedBlock.guard) {
//threadMessage("Still waiting...");
}
threadMessage("Finally!");
}
});
thread1.start();
thread2.start();
}
}
我正在通过Java Essentials教程学习并发性。找到了守卫的方块并尝试对其进行测试。我无法理解的一件事。
虽然循环是无限的,但是如果您取消注释threadMessage行,则一切正常。为什么?
简短答案
您忘了声明guard
为易失性布尔值。
如果您将字段声明省略为volatile
,则不会告诉JVM该字段可以被多线程看到,例如您的示例。
在这种情况下,的值guard
将被读取一次,并且将导致无限循环。它将针对以下内容进行优化(无打印):
if(!guard)
{
while(true)
{
}
}
现在为什么要System.out.println
改变这种行为?因为writes
是同步的,这迫使线程不缓存读取。
这里粘贴了println
一种PrintStream
使用的方法的代码System.out.println
:
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
和write
方法:
private void write(String s) {
try {
synchronized (this) {
ensureOpen();
textOut.write(s);
textOut.flushBuffer();
charOut.flushBuffer();
if (autoFlush && (s.indexOf('\n') >= 0))
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
注意同步。
我是通过java基础教程学习并发性的。到了警戒区,试着测试一下。有一件事我无法理解。 While循环是无限的,但是如果取消对threadMessage line的注释,一切都会正常工作。为什么?
我有一个看起来很简单的问题,但由于某种原因我无法绕过它。基本上我的程序正在导致一个无限循环,我不知道为什么。 下面是我陷入的特定循环: 当我运行它时,它总是问我输入列#。我给它一个数字,它接受这个数字,$response变为True,但while循环继续运行,就好像<code>的$response</code>为false一样。我是Perl新手,所以可能我遗漏了一些东西,但是($response=
我有财产课: 还有一种方法: 在类的构造函数我有: 为什么当我从object按键调用函数时。我收到一条未定义的消息,为什么变量在内部不可用:
在下面的程序中,如果我在第一条if语句中将变量$foo设置为值1,那么它的工作原理是在if语句之后记住它的值。然而,当我将同一变量设置为while语句中的if语句中的值2时,它会在while循环后被遗忘。它的行为就像我在循环中使用变量$foo的某种副本,而我只修改特定的副本。下面是一个完整的测试程序:
我正在努力解决这个问题1438。绝对差值小于或等于极限的最长连续子阵列。我明白了逻辑,但有一个非常奇怪的问题,我不得不拉扯头发两个多小时。 代码如下:- 您可以看到,当我将一个整数放入每个队列时,代码运行良好,但当我将一个int放入三个队列时,我得到一个TLE。因此,在下面的代码中,如果temp是,则代码通过,但当temp是时,它会给出一个TLE。有人能解释一下发生了什么吗?
尝试编写一个程序,其中用户输入他们一周的费用。麻烦在于我希望程序重新询问用户是否输入了不可接受的输入。我想出了如何检测负值的方法,但是当尝试捕获输入不匹配异常(如果像输入字符或字符串一样)时,循环只是无限运行,要求“星期一费用:”我如何使它,以便用户有另一个回答的机会?我试着Rest一下;但是这也打破了做而循环,我不想要。 这是我目前为止的代码: 谢谢你的帮助