I have a piece of code which looks like this:
Snippet A:
class Creature {
private static long numCreated;
public Creature() {
synchronized (Creature.class) {
numCreated++;
}
}
public static long numCreated() {
return numCreated;
}
}
From my understanding, since reading of numCreated
is not synchronized, if Thread-A creates a Creature
at 1pm, and Thread-B reads numCreated()
at 2pm, numCreated()
may well have returned either 0 or 1 (even when Thread-A has finished initializing the object at 1.05pm).
So I added synchronized
to numCreated()
:
Snippet B :
class Creature {
private static long numCreated;
public Creature() {
synchronized (Creature.class) {
numCreated++;
}
}
public static synchronized long numCreated() { // add "synchronized"
return numCreated;
}
}
and all's well, except that I was thinking, if I modify it to Snippet C , is the variable numCreated
still synchronized properly?
Snippet C:
class Creature {
private static volatile long numCreated; // add "volatile"
public Creature() {
synchronized (Creature.class) {
numCreated++;
}
}
public static long numCreated() { // remove "synchronized"
return numCreated;
}
}
With Snippet C , is it guaranteed that as soon as Thread-A completes object creation at 1:05pm, Thread-B's call to numCreated()
is sure to return 1
?
PS: I understand that in a real situation I would probably use an AtomicLong
but this is for learning purposes
A write to a volatile field happens-before every subsequent read of that same field. Writes and reads of volatile fields have similar memory consistency effects as entering and exiting monitors, but do not entail mutual exclusion locking.
So the answer is yes. The write of the volatile in the constructor happens before the read of the volatile in numCreated()
. And since the non-atomic incrementation is still done in a synchronized block, the synchronization is alright (the incrementation is not atomic, but the write of the volatile long is).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.