Prz*_*iak 7 java multithreading
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();
}
}
Run Code Online (Sandbox Code Playgroud)
我通过java essentials教程学习并发.得到防护块并试图测试它.有一点我无法理解.
虽然循环是无限的,但如果取消注释threadMessage行,一切正常.为什么?
Jea*_*ard 15
简短的回答
你忘了声明guard为volatile布尔值.
如果你省略了字段的声明volatile,那么你并没有告诉JVM多个线程可以看到这个字段,在你的例子中就是这种情况.
在这种情况下,值guard只读一次会导致无限循环.它将被优化为这样的东西(没有打印):
if(!guard)
{
while(true)
{
}
}
Run Code Online (Sandbox Code Playgroud)
现在为什么System.out.println改变这种行为?因为writes是同步的,所以强制线程不缓存读取.
这里使用的println方法之一的代码粘贴:PrintStreamSystem.out.println
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
Run Code Online (Sandbox Code Playgroud)
和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;
}
}
Run Code Online (Sandbox Code Playgroud)
注意同步.
| 归档时间: |
|
| 查看次数: |
1081 次 |
| 最近记录: |