In this chapter we discuss the use of volatile to resolve asynchronous dead loops.
1. Before we discuss the above question, we introduce another example: synchronous dead Loop
Code Listing:
Package Com.ray.deepintothread.ch03.topic_1;public class Deadfor {private Boolean isstop = False;public boolean isstop () {return isstop;} public void Setstop (Boolean isstop) {this.isstop = Isstop;} public void Test () throws Interruptedexception {while (!isstop) {System.out.println ("Thread Name:" + Thread.CurrentThread (). GetName ()); Thread.Sleep (200);}} public static void Main (string[] args) throws Interruptedexception {deadfor deadfor = new Deadfor ();d eadfor.test ();d EADFO R.setstop (True);}}
Output:
Thread Name:main
Thread Name:main
Thread Name:main
Thread Name:main
Thread Name:main
Thread Name:main
Thread Name:main
Thread Name:main
Thread Name:main
Thread Name:main
Thread Name:main
Thread Name:main
。。。。
In the example above, the test method has blocked execution of all methods behind main.
2. Ways to resolve a synchronous dead loop: Using asynchronous
Package Com.ray.deepintothread.ch03.topic_1;public class Solvedeadfor implements Runnable {Private Boolean isstop = False;public Boolean isstop () {return isstop;} public void Setstop (Boolean isstop) {this.isstop = Isstop;} public void Test () throws Interruptedexception {while (!isstop) {System.out.println ("Thread Name:" + Thread.CurrentThread (). GetName ()); Thread.Sleep (200);}} public static void Main (string[] args) throws Interruptedexception {solvedeadfor deadfor = new Solvedeadfor (); Thread thread = new Thread (deadfor); Thread.Start (); Thread.Sleep (;d eadfor.setstop (true); System.out.println ("-------stop--------");} @Overridepublic void Run () {try {test ();} catch (Interruptedexception e) {e.printstacktrace ()}}}
Output:
Thread name:thread-0
Thread name:thread-0
Thread name:thread-0
Thread name:thread-0
Thread name:thread-0
-------Stop--------
The above method we need to note is: The test method we are to start a thread to run, no longer be placed in main inside the run
Therefore, the test method and main inside the method is executed in parallel two lines, never occur intersection, will avoid the above synchronization, the test method executes, blocking the execution of all the following methods
When the wait time elapses, we trigger the state field inside the object so that the test method stops
3. Asynchronous dead Loop
Code Listing:
Package Com.ray.deepintothread.ch03.topic_1;public class Solvedeadfor {public static void main (string[] args) throws interruptedexception {Myclassone Myclassone = new Myclassone (); Myclassone.start (); Thread.Sleep (+); Myclassone.setstop (true); System.out.println ("---------stop----------");}} Class Myclassone extends Thread {private Boolean isstop = False;public Boolean isstop () {return isstop;} public void Setstop (Boolean isstop) {this.isstop = Isstop;} @Overridepublic void Run () {System.out.println ("running"), while (!isstop) {}system.out.println ("Out");}}
The above code Note: In this case, the loop inside the run must be an empty loop in order to have a dead loop.
The author estimates that Isstop is compiled by the compiler and reads local variables, so even if the domain is modified externally, it is not where we want it to be read.
JVM Settings:
Note: The JVM must be in a-server state to be able to have an asynchronous dead loop.
Output:
Running
---------Stop----------
(does not appear out)
We use the JVM's memory model to explain the above phenomenon.
Note: The picture is from the Java Multithreaded Programming core technology
As can be seen by the above memory model, when we thread up, we modify the thread's private working memory and write some values into the main memory.
Then, when we modify these working memory, we usually synchronize to the main memory.
However, the code above only modifies the working memory and not the main memory, so when we modify the working memory externally, the Isstop read in run is the main memory, and there is no modification, there will be an asynchronous dead loop.
Let's take a look at the code that does not appear in the asynchronous loop, just add one or two lines of code to the loop
Package Com.ray.deepintothread.ch03.topic_1;public class DeadForSynch2 {public static void main (string[] args) throws interruptedexception {myclasstwo Myclassone = new Myclasstwo (); Myclassone.start (); Thread.Sleep (+); Myclassone.setstop (true); System.out.println ("---------stop----------");}} Class Myclasstwo extends Thread {private Boolean isstop = False;public Boolean isstop () {return isstop;} public void Setstop (Boolean isstop) {this.isstop = Isstop;} @Overridepublic void Run () {System.out.println ("running"), while (!isstop) {System.out.println (Thread.CurrentThread ( ). GetName ()); try {sleep ($);} catch (Interruptedexception e) {e.printstacktrace ()}} System.out.println ("Out");}}
Output:
Running
Thread-0
Thread-0
Thread-0
---------Stop----------
Out
4. Asynchronous dead-loop solution
Code Listing:
Package Com.ray.deepintothread.ch03.topic_1;public class Solutionofdeadforasychn {public static void main (string[] args) throws Interruptedexception {Myclassthree myclassthree = new Myclassthree (); Myclassthree.start (); Thread.Sleep (+); Myclassthree.setstop (true); System.out.println ("---------stop----------");}} Class Myclassthree extends Thread {private volatile Boolean isstop = False;public Boolean isstop () {return isstop;} public void Setstop (Boolean isstop) {this.isstop = Isstop;} @Overridepublic void Run () {System.out.println ("running"), while (!isstop) {}system.out.println ("Out");}}
Output:
Running
Out
---------Stop----------
We use volatile above to force Isstop to the main memory so that other threads can be visible.
Summary: This section discusses the use of volatile to resolve asynchronous dead loops.
This chapter is here, thank you.
------------------------------------------------------------------------------------
My github:https://github.com/raylee2015/deepintothread.
Catalog: http://blog.csdn.net/raylee2007/article/details/51204573
Understanding multithreading from scratch-3.1 using volatile to solve asynchronous dead loops