Reputation: 1232
Is it possible to use volatile variables to allow consistent write-only synchronisation?
This is the code:
public class Controller {
Container cont = new Container();
...
public Object get(){
if(!cont.isLocked()){
return cont.getObject(); //many threads can read at the same time
}
else synchronized(cont){
return cont.getObject(); //threads wait until write is finished
}
}
public void set(Object o){
synchronized(cont){
cont.lock();
cont.setObject(o);
cont.unlock();
}
}
}
public class Container {
private volatile boolean lock = false;
private Object data;
public Container(){
}
public void lock() {
lock = true;
}
public void unlock() {
lock = false;
}
public boolean isLocked() {
return lock;
}
public void setObject(Object o) {
data = o;
}
public Object getObject() {
return data;
}
}
Will it work, or will it break, what do you think?
Upvotes: 2
Views: 63
Reputation: 328608
It may/will break. Example of execution:
if(!cont.isLocked())
returns trueset(someObject)
return cont.getObject();
returns an old versionEven worse, since you don't have a proper happens-before relationship between T2 and T1, cont.getObject()
may return the a reference to the new object created by T2, but pointing to an inconsistent/not-fully-constructed object.
You have a typical check-then-act problem.
Why don't you just use a volatile reference to your object?
public class Controller {
private volatile Object obj = new Object();
public Object get(){ return obj; }
public void set(Object o){ obj = o; }
}
That would be thread safe.
Upvotes: 5