동기화 된 휘발성 키워드/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;
}
}
지금, 나는 setY(Y)
메서드를 호출하여 변경 될 때마다 단일 스레드가 같은 개체 참조를 볼 수 있도록 volatile
로 yObj
을 선언했다. Y
클래스의 아이디어는 X
개체의 setter를 호출 할 때 X
클래스에 참조 값 집합 (이 예제에서는 하나)을 제공하는 것입니다. 질문은 다음과 같습니다
- 이
x
여전히volatile
로 선언하고 모든 스레드에 대한 공통의 시인성을 확보 또는 추가 동기화가 필요 할 수 있습니까? - 아이디어는 클래스
Y
의 모든 객체를 변경 불가능하게 만드는 것입니다. 그래서, 나는 모든 필드가 불변 이어야만한다고 가정합니다.Y
사용자를 구현 가능하게 만드는 가장 좋은 방법은 무엇이지만 동시에 스레드로부터 안전합니까? 스레드 안전 메커니즘을 구현 한 추상 클래스는 확장 가능합니까? 현재Y
은 스레드 세이프가 아닌 getter 메소드를 구현할 수있는 인터페이스입니다. - 동시 액세스의 관점에서 시작/중지 메커니즘이 올바르게 구현 되었습니까?
예를 들어,'setY'는 2 개의 비동기 조작을 사용합니다. 'getX()'는 새로운'x'를 보지 않고 새로운'yObj'를 보게됩니다. 잠재적으로 스레드 세이프가 아닙니다. 또한'setX'와'setY'는 안전하지 않습니다. setX의 x로 끝날 수 있지만 setY – zapl
의 y는 맞습니다. 그 점을 지적 해 주셔서 감사합니다! – acostalima