Java 函数内部的多线程变量访问
我有一个函数,它启动两个线程(这是一个测试函数),其中一个线程改变变量的状态。由于局部变量不能标记为volatile,因此我假设该方法中的多个线程将始终具有变量的更新状态。这是正确的吗?下面是示例代码Java 函数内部的多线程变量访问,java,variables,multithreading,Java,Variables,Multithreading,我有一个函数,它启动两个线程(这是一个测试函数),其中一个线程改变变量的状态。由于局部变量不能标记为volatile,因此我假设该方法中的多个线程将始终具有变量的更新状态。这是正确的吗?下面是示例代码 public void someMethod() { MutableBoolean mb = new MutableBoolean(false); Thread t1 = new Thread() { public void run() { whil
public void someMethod() {
MutableBoolean mb = new MutableBoolean(false);
Thread t1 = new Thread() {
public void run() {
while (someCondition) {
if ( mb.getValue() ) {
...do something
}
}
}
}
t1.start();
Thread t2 = new Thread() {
public void run() {
if ( someCondition ) {
mb.setValue(true);
}
}
}
t2.start();
...wait for the threads to complete
}除非MutableBoolean在其set/get value方法中使用锁,或者它是一个原子操作,否则这不是线程安全的 getValue可能正在读取该值,而setValue正在更新该值。您可以使用布尔值来解决这个问题,但对于任何更复杂的类型,它都可能失败
对共享状态的访问设置一个锁,以使其线程安全。要实现线程间的可见性,volatile不是唯一的选项。任何同步(锁定)也将起作用 在本例中,MutableBoolean可以是线程安全的类,这样就可以完成这项工作
正如danben所说,可变布尔值可能需要
final
才能传递给函数
发布前是否在IDE中测试了代码?mb必须定义为final,否则代码将无法编译(匿名类只能访问声明范围的final变量)。最后一个变量不能改变它的值,所以从技术上讲,t1和t2在mb处总是看到相同的值。因此,mb是否易失性的问题无关紧要
您的问题不是mb对象本身的状态(MutableBoolean对象的字段所持有的值)。对于这些字段,您可以使用volatile和/或synchronized方法来确保线程安全。前面的海报是正确的,如果不将mb设为final,此代码将无法编译。对于引用类型,final意味着您不能更改变量引用的对象。它并不表示您不能更改该对象的状态。因此,您不能让mb引用不同的可变布尔实例,但setValue(…)将一如既往地工作。MutableBoolean.getValue()和MutableBoolean.setValue(…)应该同步,以便一个线程可以看到彼此的更改 请注意,无法保证两个新线程中的语句将以什么顺序运行。t2或t1可能首先运行,或者指令可能是交错的 这一切都不受mb是局部变量这一事实的影响,除非它是最终变量
请参阅,以获取关于此主题的确切词语。我认为它是可变布尔mbI,我认为它是mb。这段代码可以编译吗?我原以为你不能在匿名内部类中引用mb,除非它是最终的。谢谢。我知道我也需要让它成为最终版本(尽管我不认为你做出了那样的评论)。这只是示例代码,不一定是完全编译的。