Java 从外部获取线程变量的值
假设我有一个线程运行如下:Java 从外部获取线程变量的值,java,multithreading,Java,Multithreading,假设我有一个线程运行如下: private boolean working = true; @Override public void run() { working = true; // do something working = false; .... } 在我的主线中,我不断地展示与他人合作的状态 while(threadClassObject.isWorking()) { System.out.println(threadClassObject.is
private boolean working = true;
@Override public void run() {
working = true;
// do something
working = false;
....
}
在我的主线中,我不断地展示与他人合作的状态
while(threadClassObject.isWorking()) {
System.out.println(threadClassObject.isWorking());
}
这样行吗?我试过这个例子,它似乎有效。但有没有办法让它崩溃?例如,当主线程试图读取线程时,如果线程正在更改工作状态,会发生什么情况?您需要使用同步或AtomicBoolean以确保线程安全。代码中的内容似乎有效,但检查布尔值时,它可能不是正确的值,因此您将看到意外的结果。不,没有必要像布尔值那样锁定基元类型。如果“working”是一个对象,那么您需要使用同步块。您的问题的答案是,它可能正在工作,但上面的代码是一个风险代码,随时可能中断。尝试使
工作
易失性
类似
private volatile boolean working = true;
例如,如果线程正在更改工作状态,而主线程正试图读取它,会发生什么情况?
赋值操作是一种原子操作。因此,如果您只有一个cpu,那么在访问变量时,两个线程永远不会发生冲突。如果您有多个cpu,那么在访问变量时,两个线程可能会发生冲突。对于这两种情况,volatile
将确保该值对其他线程可见
注意:volatile
在您的情况下是好的,但是如果您有更复杂的数据要跨线程共享的话
编辑:
添加注释也是解决方案的一部分,以使其更加清晰
基本上,在cpu级别的优化中,一个线程更改的值可能对另一个线程不可见。cpu缓存bcoz优化就是一个很好的例子。在其他线程可能正在读取的ram中,这些值永远不会反映出来。Volatile告诉您,此变量的值可以在当前线程的范围之外更改,因此不会进行此类优化…您可能还希望在主线程中的“失控”while循环中进行一些操作:
当前的实现将继续旋转,不会为执行
run()
(或系统中的任何其他人)的线程留下太多CPU时间。如果它不是易失性的
,那么isValue()
在主线程调用中调用可能看不到更改的值。在部分状态下观察布尔值没有危险,但是您仍然会遇到麻烦:除非程序通过某种同步与写和读建立“发生在之前”的关系,否则无法保证主线程会在子线程中看到写操作。这与工作是对象还是原语无关。具体来说,Thread.sleep
和Thread.yield
都是防止这种情况发生的简单方法。一个更健壮的解决方案是将程序重组为事件驱动的,或者其他什么。谢谢,我只是以这种方式进行循环来测试它,所以我不断地访问线程变量。好的,谢谢大家的回答,现在我已经将它改为volatile。如果它们相撞,到底会发生什么?因为我现在已经做了两个无休止的循环,一个在不断改变工作变量的线程中,另一个在不断检查工作变量的主线程中,但什么也没有发生。基本上,在cpu级别的优化中,一个线程中改变的值可能对另一个线程不可见。cpu缓存bcoz优化就是一个很好的例子。在其他线程可能正在读取的ram中,这些值永远不会反映出来。Volatile告诉我们,这个变量的值可以在当前线程的范围之外更改,所以不会进行这样的优化。。。