我已经阅读了很多关于同步和可变关键字/idms 的帖子,我认为我正确理解了它们的工作原理以及何时使用它们。但是,我仍然对我正在尝试做的事情有些怀疑。考虑以下:
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
X
- 仍然可以
x
声明为volatile
并确保所有线程的共同可见性或需要进一步同步? - 这个想法是使类的所有对象
Y
不可变。因此,我假设它的所有字段也必须是不可变的。使Y
用户可实现但同时又是线程安全的最佳方法是什么?一个实现线程安全机制然后可以扩展的抽象类?目前,Y
是一个带有getter方法的接口,可以实现,当然不是线程安全的。 - 从并发访问的角度来看,启动/停止机制是否正确实现?