patternjavaMinor
Does this Actor implementation has synchronization problems?
Viewed 0 times
thisactorsynchronizationhasdoesimplementationproblems
Problem
As a part of a job test, I wrote following implementation of the Actor execution model:
Reviewers concluded, in particular, that "Actor class have synchronization issues", but did not want to explain why.
Can you see any synchronization problems here?
The code, along with a test, can be downloaded from https://github.com/rfqu/CodeSamples/tree/master/src/simpleactor.
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.Executor;
public abstract class Actor implements Runnable {
private final Executor executor;
/** current token */
private Message message=null;
/** rest of tokens */
private Queue queue = new LinkedList();
private boolean isFired=false;
public Actor(Executor executor) {
this.executor = executor;
}
/**
* Frontend method which may be called from other Thread or Actor.
* Saves the message and initiates Actor's execution.
*/
protected void post(Message message) {
synchronized(this) {
if (isFired) {
queue.add(message);
return;
}
this.message=message;
isFired=true; // to prevent multiple concurrent firings
}
executor.execute(this);
}
@Override
public void run() {
for (;;) {
this.message.run();
synchronized(this) {
this.message = queue.poll(); // consume token
if (this.message==null) {
isFired=false; // allow firing
return;
}
}
}
}
protected abstract class Message {
protected abstract void run();
}
}Reviewers concluded, in particular, that "Actor class have synchronization issues", but did not want to explain why.
Can you see any synchronization problems here?
The code, along with a test, can be downloaded from https://github.com/rfqu/CodeSamples/tree/master/src/simpleactor.
Solution
There is a problem.. You
In order to make things right
post() your message and it gets assigned in synchronized block, but it gets accessed in non-synchronized block. The field is not volatile therefore even though the reference to this.message might be visible to ThreadB, the inner state of the object might be still invisible. So message.run() may get you into a trouble.In order to make things right
this.message should be marked as volatile. Read about safe publishing in Java for more details.Context
StackExchange Code Review Q#28653, answer score: 3
Revisions (0)
No revisions yet.