Just give me an example. Non-visibility of normal thread instance variables:
Public classMyThread28extendsthread{Private BooleanIsRunning =true; Public Booleanisrunning () {returnisrunning; } Public voidSetrunning (Booleanisrunning) { This. isrunning =isrunning; } Public voidrun () {System.out.println ("Into run."); while(IsRunning = =true) {} System.out.println ("The thread is stopped."); }}
Public Static voidMain (string[] args) {Try{MYTHREAD28 Mt=NewMyThread28 (); Mt.start (); Thread.Sleep (1000); Mt.setrunning (false); System.out.println ("Assigned value is False"); } Catch(interruptedexception e) {e.printstacktrace (); }}
Look at the results of the operation:
Entered run, assigned to False
Perhaps the result is a bit strange, obviously isrunning has been set to false, the thread has not stopped it?
This is going to start with the Java memory Model (JMM), where the virtual machine will be described in detail. Depending on the main memory in the Jmm,java, different threads have their own working memory, and the same variable value has one copy in main memory, and if the thread uses this variable, it has an identical copy in its working memory. Each time the thread enters the variable value from main memory, the thread synchronizes the variable from the working memory back into main memory each time it executes.
Note that the situation here will only appear in the server mode, the client mode will not appear, and to sleep for a period of time and then set false, it is estimated that the child thread read load good main memory field bar, do not set sleep, child thread too late read load will immediately stop
The reason for the printing result is that the main memory and the data in the working memory are not in sync. Because the run () method is executed with a copy of the main memory isrunning, and the setup isrunning is done in the main function, in other words, the isrunning setting is the isrunning in main memory, and the isrunning of the main memory is updated , the isrunning in the thread's working memory is not updated, and of course it has been looped, because for the thread, its isrunning is still true.
Solving this problem is simple, add volatile to the IsRunning keyword. Adding volatile means that each time the value of isrunning is read, the isrunning is synchronized from the main memory to the working memory of the thread, and then the current time is the latest isrunning. Take a look at the run effect of the volatile keyword for isrunning:
Entered run, the assigned value is False, the thread is stopped.
See this thread stopped because the most recent isrunning value was read from main memory, the isrunning in the thread's working memory became false, and the natural while loop ended.
Normal thread memory model prior to volatile
Use volatile after
Here you can refer to the memory model of the Java Virtual machine 9:java
volatile's role is this, the volatile modifier of the variable, to ensure that each read is the most recent value. Thread safety revolves around the Visibility and Atomic two features, < Strong style= "margin:0px; padding:0px ">volatile addresses the visibility of variables across multiple threads, but there is no guarantee of atomicity .
to mention, synchronized in addition to the protection of atomicity, in fact, it also protects the visibility. Because synchronized either synchronous or synchronized blocks of code, the primary memory data is copied into working memory ( synchronized as long as the thread calls, no matter who you lock, as long as the process-related instance variables, static variables will be synchronized to the main memory, to achieve visibility, the following can see the example
volatile non-atomic properties
Run results
Proof of non-atomicity, but guaranteed to be visible
The following change code uses synchronized instead of volatile
Run results
using synchronized, there's no need to use volatile.
synchronized has a volatile sync function
you can see it. synchronized as long as the thread calls, no matter who you lock, as long as the process-related instance variables, static variables will be synchronized to the main memory, to achieve visibility
Java Multithreading 11:volatile Keywords