Java – synchronization, volatile and thread safety

I'm reading some books about Java concurrency recently With regard to thread safety, if you cannot make a class immutable, you can always ensure thread safety by synchronizing its data

The following classes are obviously not thread safe

public class NotThreadSafe {
  private int value;

  public void setValue(int value) {
    this.value = value;
  }

  public int getValue() {
    return this.value;
  }
}

Then I can write synchronously, but it's still not thread safe

public class StillNotThreadSafe {
  private int value;

  public synchronized void setValue(int value) {
    this.value = value;
  }

  public int getValue() {
    return this.value;
  }
}

Because I need not only synchronous writing, but also synchronous reading

public class ThreadSafe {
  private int value;

  public synchronized void setValue(int value) {
    this.value = value;
  }

  public synchronized int getValue() {
    return this.value;
  }
}

The problem now is that by using volatile, I can ensure that other threads will see the updated value, so this makes me think this class should be thread safe

public class NotSure {
  private volatile int value;

  public synchronized void setValue(int value) {
    this.value = value;
  }

  public int getValue() {
    return this.value;
  }
}

The last class is thread safe??

Solution

Short answer:

Yes, but in the last case, you don't even need to sync The only thing setValue can do is a single operation, a write operation - the volatility in each operation is atomic That is, every write is atomic and every read is atomic

Longer answer:

Of course, if you try to add value using the following mode:

NotSure ns = new NotSure();
int v = ns.getValue();
ns.setValue(v + 1);

... so this is not thread safe because it involves ns Value (read and write), while volatile only gives you the atomicity of one operation In this case, even adding to getters and setters synchronously is not enough, because operations can be injected between two method calls

The last point is actually a rebuttal to the claim that "you can ensure thread safety by synchronizing [object's] data" If you want a thread safe way to add notsure Value, you need to synchronize the entire incremental operation, not just access the object's data In this case, you need to synchronize the setter because it can insert itself between the operations of the incremental method Getters still don't need to be synchronized because the volatile keyword ensures that getters get pre - or post - incremented values

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
分享
二维码
< <上一篇
下一篇>>