The most basic purpose of synchronization is to ensure atomicity. Another easy-to-ignore objective is visibility, that is, the shared data modified by one thread is visible to another thread.
Some basic assignment operations are atomic. Therefore, if you do not use synchronized for these assignment operations, you can use volatile to solve the problem of visible modifications of one thread to another. So volatile is a way to avoid using synchronized for visibility while ensuring atomicity.
Private Static volatile int nextserialnumber = 0;
Public static int generateserialnumber (){
// Because the "value assignment" such as nextserialnumber ++ is actually divided into multiple steps. In this way, the following method cannot guarantee atomicity.
Return nextserialnumber ++;
}
Improvement:
Private Static int nextserialnumber = 0;
// If synchronized is used, volatile can be omitted. The latter ensures visibility.
Synchronized public static int generateserialnumber (){
Return nextserialnumber ++;
}
Or:
// Atomiclong is a cam mechanism that ensures visibility and atomicity.
Private Static final atomiclong nextserialnum = new atomiclong ();
Public static long generateserialnumber (){
Return nextserialnum. getandincrement ();
}