java - 无法调用线程
问题描述
class client
{
static int data = 0;
public static void main(String[] args)
{
new Thread(new Runnable()
{
@Override
public void run()
{
while(true)
{
//System.out.print("");
if(data == 1) {System.out.println("GOTCHA");}
}
}
}).start();
Scanner sc = new Scanner(System.in);
while(true)
{
data = sc.nextInt();
}
}
}
我不明白为什么当我输入 1 时它不起作用。还有一个有趣的情况是,如果我删除评论(System.out.print(“”)),它会起作用。我可以用另一种方式,比如回调方法,只是我想要的是为什么它不起作用。
解决方案
简短的版本是共享变量应该被声明为volatile
或者访问/更新变量应该使用适当的同步机制来完成。适当的同步机制可以是:
使用原始监视器;即
synchronized
具有相同目标对象的块或方法。在同一个锁对象上使用
Lock.acquire
和。Lock.release
Something else with appropriate happens before relationships. (Don't worry about this case. It is complicated. But if you want to, read up about the Java Memory Model.)
At any rate, if two threads share a (non-volatile) variable without appropriate synchronization, then one thread is not guaranteed1 to see the value written by the other thread. That is what was happening with your example. The child thread never sees the results of the parent thread's write.
This is normal behavior with multi-threading in Java. And one of the reasons why concurrent programming in Java is tricky.
1 - In some cases the data will be visible, and others it won't. It can depend on the Java version, the operating system, the hardware platform, whether you are debugging or not, and various other things. There are at least two possible causes of the visibility issues. 1) It is often due to memory caching issues; e.g. changes made by one thread not being flushed to main memory so that the other thread can see them. 2) Alternatively, it could (in theory at least) be due the JIT compiler optimizing away memory fetches. To understand exactly what is going on, you would need to analyze the native code emitted by the JIT compiler. But either way, these behaviors are permitted by the Java Memory Model ... if the required happens before relationships do not exist.
推荐阅读
- regex - 使用标准重命名文件
- python - 对具有多个约束的表执行 Sql Alchemy On_conflict_do_update
- javascript - Vue过滤器状态数组
- python - 限制命令的问题,discord.py
- jquery - 如何将变量添加到已经连接的选择器?
- java - 我们可以在 Java/Spring 应用程序中使用用 Scala 编写的域模型吗?
- python - Firefox 中的 Selenium“请验证您是人类”弹出窗口
- python - 如何直接从cmd打开Jupyter而不是复制链接
- java - 应用程序启动方法中的异常 java.lang.reflect.InvocationTargetException 和更多 JavaFx 错误
- google-cloud-platform - 在 BigQuery 中使用 UDF 时是否可以在窗口之间保持共享状态?