java - 我的类是否是线程安全的,有多个线程访问其变量?

标签 java concurrency thread-safety synchronized

当我试图掌握线程安全时,我想知道这个类是否是线程安全的?如果两个线程在任何时候尝试访问它的变量,在我看来它是线程安全的,因为:

  • final 变量由于不可变而具有线程安全性。
  • getter 和 setter 是同步的,因此 mObject 一次只能由一个线程获取或设置。因此两个线程不可能读取不同的值。
  • 方法changeObj()不是同步的,但其中处理类变量(即mObject)的任何 block 都是同步的。

如果我错了或者这个类不是线程安全的,请告诉我。

public class MyClass{

   private final String = "mystring"; //thread safe because final
   private AnObject mObject;

   public MyClass(){
       //initialize
   }

   //only one class can set the object at a time.
   public synchronized void setObj(AnObject a){
      mObject = a;
   }

    //two threads trying to get the same object will not read different values.
   public synchronized AnObject getObj(){
      return mObject;
   }

   //better to synchronize the smallest possible block than the whole method, for performance.
   public void changeObj(){
       //just using local variables (on stack) so no need to worry about thread safety
       int i = 1;
       //i and j are just to simulate some local variable manipulations.
       int j =3;
       j+=i;
       synchronized(this){
          //change values is NOT synchronized. Does this matter? I don't think so.
          mObject.changeValues();
      }
   }
}

最佳答案

不,它不是线程安全的。如果使用 changeObj() 方法,则确保一次只有一个线程可以更改 AnObject 中的值,但您还为此对象提供了一个 getter,因此任何其他线程都可以同时调用 changeValues()

关于java - 我的类是否是线程安全的,有多个线程访问其变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12826099/

相关文章:

java - 放弃音频焦点并继续之前的音乐/视频流

java - Camel路线是如何手动启动的?

java - 将 java 泛型用于简单工厂 - 如何避免这些警告

java - Eclipse 导出到可运行的 JAR - 类路径上的类文件未找到或无法访问 :

C# 系统参数异常 : Destination array was not long enough

java - 在模拟中移动多辆车的有效方法

java - 进一步并行化两个Java的parallelStream()计算

go - 有人可以解释这个使用 channel 的 Go 代码块吗?我不明白它是如何一次执行 500 个 Action 的

java - 为什么在 Java 的新 Collection 库中牺牲了线程安全?

java - 了解Java中的同步块(synchronized block)