Java – volatile semantics relative to other fields

Suppose I have the following code

private volatile Service service;

public void setService(Service service) {
  this.service = service;
}

public void doWork() {
  service.doWork();
}

The modified field is marked volatile, and its value does not depend on the previous state Therefore, this is the correct multi-threaded code (don't bother the service implementation in a minute)

As far as I know, reading volatile variables is like entering a lock, from the perspective of memory visibility This is because reading normal variables cannot be reordered by reading volatile variables

Does this mean that the following code is correct?

private volatile boolean serviceReady = false;
private Service service;

public void setService(Service service) {
  this.service = service;
  this.serviceReady = true;
}

public void doWork() {
  if ( serviceReady ) {
    service.doWork();
  }
}

Solution

Yes, this code is "correct", just like Java 1.5

Atomicity is not a problem, with or without volatile (writes to object references are atomic), so you can transfer the relationship list from this relationship list in any way - the only problem is the visibility of changes and the "correctness" of sorting

Any writing to volatile variables will set a "before occurrence" relationship (the key concept of the new JAVA memory model, as described in jsr-133), and the same variables can be read at the same time This means that the reading thread must be able to see everything visible to the writing thread: that is, it must see at least all variables with a 'current' value when writing

We can view section 17.4 5 of the Java language specification explains this in detail, and the specific points are as follows:

>"If x and y are actions of the same thread and X appears before y in the program sequence, then HB (x, y)" (that is, actions on the same thread cannot be reordered in a manner inconsistent with the program sequence) > "writing volatile fields (§ 8.3.1.4) occurs before each subsequent reading of the field." (this is a clear text explaining that the write and immediate read of volatile fields are synchronization points) > "if HB (x, y) and Hb (y, z), then HB (x, z)" (transitivity before occurrence)

So in your example:

>Writing 'service' (a) occurs before writing 'serviceready' (b). Since rule 1 > rule 2, writing "serviceready" (b) occurs before reading of the same (c), therefore, (a) occurs before (c) (Rule 3)

This means that you ensure that 'service' is set correctly. In this case, once serviceready is true

You can see some good writing using almost identical examples, one at IBM developerWorks – see "new volatile assurance":

And one in the jsr-133 FAQ, written by the author of JSR:

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>