线程安全代码 不可变对象 - CunDeveloper/com.nju.edu.cn.software.school.friend.service GitHub Wiki

什么是线程安全代码

条件竞争是指当多个线程访问同一个资源时,并且有一个或多个线程对此资源进行修改。即当多个线程只去读同一个资源时,条件竞争不会出现。 当一个对象为不开变对象时,线程共享的此对象是安全的。下面的代码是线程安全代码

public class ImmutableValue{

   private int value = 0;

   public ImmutableValue(int value){
     this.value = value;
   }

   public int getValue(){
     return this.value;
   }
}

代码说明:因为ImmutableValue实例对象中的value值只能读,不能修改。即在多个线程共享ImmutableValue对象实例时不会出现条件竞争。

如果你需要在ImmutableValue实例变量上执行一些新的操作,你需要返回一个新的实例变量。即每个线程对应一个ImmutableValue的实例变量。同样不会出现条件竞争,代码如下:

public class ImmutableValue{

  private int value = 0;

  public ImmutableValue(int value){
    this.value = value;
  }

  public int getValue(){
    return this.value;
  }


  public ImmutableValue add(int valueToAdd){
      return new ImmutableValue(this.value + valueToAdd);
  }

}

当不可变对象作为一个对象的引用变量有可能此对象不是线程安全的

代码如下:

public class Calculator{
  private ImmutableValue currentValue = null;

  public ImmutableValue getValue(){
    return currentValue;
  }

  public void setValue(ImmutableValue newValue){
    this.currentValue = newValue;
  }

  public void add(int newValue){
    this.currentValue = this.currentValue.add(newValue);
  }
}

代码解释:类Calculator 引用了一个ImmutableValue实例变量。然而通过setValue()和and()的方法改变ImmutableValue实例变量是可能的。因此,经管Calculator引用了ImmutableVlaue的不可变实例变量。但是Calculator本身是可变对象,因此Calculator不是线程安全的。