Isn't it possible that the last value of value in thread 1 can still be "one"?
Yes it is. The java memory model is based on happens before (hb) relationships. In your case, you only have getInstance
exit happens-before subsequent getInstance
entry, due to the synchronized keyword.
So if we take your example (assuming the thread interleaving is in that order):
// Thread 1
GlobalData d = GlobalData.getInstance(); //S1
d.setData("one");
// Thread 2
GlobalData d = GlobalData.getInstance(); //S2
d.setData("two");
// Thread 1
String value = d.getData();
You have S1 hb S2. If you called d.getData()
from Thread2 after S2, you would see "one". But the last read of d is not guaranteed to see "two".