Java 函数内部的多线程变量访问

Java 函数内部的多线程变量访问,java,variables,multithreading,Java,Variables,Multithreading,我有一个函数,它启动两个线程(这是一个测试函数),其中一个线程改变变量的状态。由于局部变量不能标记为volatile,因此我假设该方法中的多个线程将始终具有变量的更新状态。这是正确的吗?下面是示例代码 public void someMethod() { MutableBoolean mb = new MutableBoolean(false); Thread t1 = new Thread() { public void run() { whil

我有一个函数,它启动两个线程(这是一个测试函数),其中一个线程改变变量的状态。由于局部变量不能标记为volatile,因此我假设该方法中的多个线程将始终具有变量的更新状态。这是正确的吗?下面是示例代码

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,除非它是最终的。谢谢。我知道我也需要让它成为最终版本(尽管我不认为你做出了那样的评论)。这只是示例代码,不一定是完全编译的。