The volatile keyword is believed to be clearly understood by readers who understand Java multithreading. The volatile keyword is used to declare simple type variables, such as int, float, and boolean data types. If these simple data types are declared as volatile, their operations will change to atomic level. But there are some restrictions. For example, N in the following example is not atomic:
Public class jointhread extends thread {public static volatile int n = 0; Public void run () {for (INT I = 0; I <10; I ++) {try {n = n + 1; sleep (3); // delay of 3 ms} catch (interruptedexception e) {e. printstacktrace () ;}}// public static int n = 0; // public static synchronized void Inc () {// n ++; ///} // public void run () {// For (INT I = 0; I <10; I ++) {// try {// Inc (); // n = n + 1 is changed to Inc () // sleep (3); // to make the running result more instant, 3 ms latency //} catch (interruptedexception e) {// E. printstacktrace (); //} public static void main (string [] ARGs) throws interruptedexception {int T = 1000; int p = 0; while (t = 1000 & P <1000) {system. out. println ("n =" + jointhread. n); thread threads [] = new thread [100]; for (INT I = 0; I <threads. length; I ++) {// create 100 threads [I] = new jointhread ();} For (INT I = 0; I <threads. length; I ++) {// run the first thread threads [I] just created. start () ;}for (INT I = 0; I <threads. length; I ++) {// after all the 100 threads are executed, continue threads [I]. join ();} system. out. println ("n =" + jointhread. n); t = jointhread. n; P ++; jointhread. n = 0;} system. out. println ("n =" + jointhread. n); system. out. println ("P =" + p );}}
The execution result is as follows:
If the operation on N is atomic, the final output result should be n = 1000. When executing the code above, it is obvious that the output N is less than 1000, this indicates that n = n + 1 is not an atomic operation. The reason is:Simple variable declared as volatileIf the current value is related to the previous value of the variable,The volatile keyword does not work.In other words, the following expressions are not atomic operations:
N = n + 1;
N ++;
If you want to change this situation to an atomic operation, you need to use the synchronized key.. Comment out the following code, restore the original code, and re-execute the program.
Public static volatile int n = 0;
Public void run (){
For (INT I = 0; I <10; I ++ ){
Try {
N = n + 1;
Sleep (3); // delay of 3 ms to make the running result more instant
} Catch (interruptedexception e ){
E. printstacktrace ();
}
}
}
The execution result is as follows:
The code above changes n = n + 1 to Inc (), where the INC method uses the synchronized keyword for method synchronization. Therefore, exercise caution when using the volatile keyword. Instead of modifying a simple type variable with volatile, all operations on this variable are atomic operations, when the value of a variable is determined by its previous one,For example, n = n + 1, n ++, and so on, the volatile keyword will be invalid. The operation on the variable is atomic level only when the value of the variable is irrelevant to the previous value,For example, if n = m + 1, this is the original level. Therefore, be cautious when using volatile,If you are unsure, you can use synchronized instead of volatile.
Article transferred from: http://longshuai2007.blog.163.com/blog/static/14209441420116214435199/
Volatile and synchronized keywords