繁体   English   中英

Java类中的线程安全性

[英]Thread safety in Java class

为什么这个java类不是Thread安全的。

class TestClass {  
   private int x;

   int get() {
       return x;
   }

   void set(int x) {
       this.x = x;
   }  
}

我读到需要关键字synchronized以使其线程安全吗? 毕竟不是在原子内完成的操作?

尽管赋值本身是一个原子操作,但由于硬件和编译器的实现不同,不同的线程可能会看到成员x的不同值。 即,由于某种缓存,一个线程的修改对于另一个线程可能是不可见的。 这通常称为线程可见性问题

您可以通过在监视器上同步(使用synchronized关键字或java.util.concurrent锁)或声明x为volatile来正确同步代码。

对于多个处理器,处理器可以缓存某些值,并且可能不反映其他线程/处理器对相同对象所做的更改。 实际上,即使使用单个处理器,也可以实现JVM以这种方式工作。

语言规范明确要求同步方法提供内存屏障,并要求重新读取内存中的所有实例变量。

因为您的代码未同步,所以一个线程可以设置该值,但另一个线程将返回该线程仍然缓存的值。

请阅读Java语言规范的“内存和锁定”一章。

由于字段“x”未声明为volatile,因此不需要JVM确保“x”对所有其他线程可见。 也就是说,如果一个线程不断地读取'x'的值并且另一个线程正在写它,那么读取线程可能永远不会“看到”值的变化。

不需要synchronized关键字,但它将起作用,因为它将创建必要的内存屏障/缓存刷新以确保'x'可见,但在这种情况下使用volatile关键字将更有效。

当你有两个修改/访问非易失性变量的方法时,它永远不是线程安全的。 如果您只想尝试一种方法,可以尝试:

synchronized int getAndSet(int x, boolean set) {
    if (set) this.x = x;
    return this.x;   // param x is for set
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM