我已经阅读了很多关于同步和易失性关键字/idom的文章,我想我正确地理解了它们是如何工作的,以及何时应该使用它们。不过,我还是对我要做的事有些怀疑。请考虑以下几点:

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对象的setter时提供X类的一组引用值(在本例中仅为一个)。问题是:
是否仍可以将X声明为x并确保所有线程的公共可见性,或者需要进一步同步?
其思想是使类的所有对象都是不可变的。所以,我假设它的所有字段都必须是不可变的。使volatile用户可实现但同时又具有线程安全性的最佳方法是什么?一个抽象类,它实现了线程安全机制,然后它就可以扩展了?目前,Y是一个带有getter方法的接口,当然,它不能实现线程安全性。
从并发访问的角度来看,启动/停止机制是否正确实现?

最佳答案

问题的关键在于private volatile Y yObj;只会使yObj引用volatile,而不是其内容。
当您稍后执行x = yObj.getY();时,您可能会请求访问一个非易失性变量,理论上这可能会导致线程不安全。
使yObj不可变可能会有帮助,但执行起来会很困难。
你的启动/停止机制看起来不错,但我会使用一个AtomicBoolean,放下同步并使用if(active.compareAndSet(false, true) { ...或类似的。

关于java - 并发访问:波动性和同步,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17901593/

10-11 10:57