并发访问:波动性和同步性

时间:2013-07-27 19:22:35

标签: java

我一直在阅读很多关于同步和易变的关键字/ idoms的帖子,我想我已经正确理解它们是如何工作的以及何时应该使用它们。但是,我仍然对我正在尝试做的事情有些怀疑。请考虑以下事项:

public class X {
  private volatile int x;

  public X(int x) {
    this.x = x;
  }

  public void setX(int x) {
    this.x = x;
  }  

  public int getX() {
    return x;
  }
} 

上面的内容非常简单且线程安全。现在考虑相同的类X,并进行以下更改:

public class X {
  private volatile int x;
  private volatile Y yObj;
  private volatile boolean active;

  public X(Y yObj) {
    this.yObj = yObj;
    active = false;
    x = yObj.getY();
  }

  public void setX(int x) {
    if (active) throw new IllegalStateException()
    if (!yObj.isValid(x)) throw new IllegalArgumentException();
    this.x = x;  
  }

  public void setY(Y yObj) {
    if (active) throw new IllegalStateException();
    this.yObj = yObj;
    x = yObj.getY();
  }

  public int getX() {
    return x;
  }

  public Y getY() {
    return yObj;
  } 

  public synchronized void start() {
     if (active) throw new IllegalStateException();
     /*
      * code that performs some initializations and condition checking runs here
      * does not depend on x and yObj
      * might throw an exception
      */
      active = true;
  }

  public synchronized void stop() {
      if (!active) throw new IllegalStateException();
      /* some code in the same conditions of the comments in the start()
       * method runs here
       */
      active = false;
  }

  public boolean isActive() {
    return active;
  }
} 

现在,我将yObj声明为volatile,以确保每个线程在通过调用setY(Y)方法进行更改时看到相同的对象引用。 Y类的想法是在调用X对象的setter时为X类提供一组参数值(在此示例中只是一个)。问题是:

  1. x仍然可以声明为volatile,并确保所有线程的公共可见性或需要进一步同步吗?
  2. 这个想法是让类Y的所有对象都是不可变的。所以,我假设它的所有字段也必须是不可变的。什么是使Y用户可实现的最佳方法,但同时又是线程安全的?一个实现线程安全机制的抽象类,然后它可以扩展吗?目前,Y是一个可以实现的getter方法的接口,当然,这不是线程安全的。
  3. 从并发访问的角度来看,启动/停止机制是否正确实现?

1 个答案:

答案 0 :(得分:1)

问题的关键在于private volatile Y yObj;仅生成yObj引用volatile,而不是其内容。

当您稍后执行x = yObj.getY();时,您可能正在请求访问非易失性变量,理论上该变量可能导致线程不安全。

使yObj永久不变可能会有所帮助,但执行这将很困难。

您的启动/停止机制看起来不错,但我会使用AtomicBoolean,删除同步并使用if(active.compareAndSet(false, true) { ...或类似内容。