How can I ensure the write operation will never be performed after close operation by using volatile variable?

ZumiKua :

Consider the following code:

Thread A:
closed = true; // closed is a volatile variable
close();

Thread B:
while(true){
  if(!closed){
    write();
  }
  else {
    ...
  }
}

If I understand correctly, closed = true; happens-before close();, and closed = true; happens-before write();, but it seems that there is no happens-before relationship between close(); and write();.

Does the above code ensures that write(); will only get called before close()? If it does not, what modification can be done to make it work? Or do I have to use synchronized?

diginoise :

You cannot guarantee that close() happens before write().

You have volatile closed as semaphore of sorts. You can use that to signal events, but you should not use it to guarantee mutual exclusion. In your case Thread A can signal to Thread B (A is writing to, B reading from volatile variable) but Thread A cannot receive a signal from Thread B which leads to a Problematic Situation described below.

volatile only guarantees that reads will see the most recent writes but does not guarantee that your write will happen before your read.

The Problematic Sutuation:

Thread B could be in the middle of write() while Thread A flips closed = true and proceeds to execute close().

Use explicit locking by protecting entire execution of write() and use the same lock to ensure that you are not calling close() while writing is happening. You can do that by synchronizing on the same object as per Mangat's answer or use ReadWriteLock from SDK.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=144289&siteId=1