Excerpt from << Zhang Xiaoxiang-java multi-threading and concurrent libraries advanced applications >>
Topic Overview
The main thread executes 10 times and then the child thread executes 5 times and then the main thread executes 10 sub-thread execution 5 times .... has been circulating 50 times.
First we should understand that our threading logic is
"The main thread executes 10 times and then the sub-thread executes 5 times"
As for loops 50 times is not our most core business logic.
So we first put the "main thread execution 10 times then the sub-thread executes 5 times" into a class.
The first step
Class business{ public void Main (int j) { //j as the largest of the 50 cycles for (int i=1;i<=10;i++) System.out.println ("main" +i+ "of Loop" +j); } Public void Sub (int j) { //j as the largest of the 50 cycles for (int i=1;i<=5;i++) System.out.println ("sub" +i+ "of Loop "+j);} }
And then it's easy for us to make a call to the class
public class traditionalcommunication{public static void Main (string[] args) { final business b=new Business ( ); New Thread ( new Runnable () {public void run () {for (int i=1;i<=50;i++) b.sub (i); } } ). Start (); for (int i=1;i<=50;i++) b.main (i);} }
If this is the code to run now. The results must have been messy.
Perhaps the parent thread has just walked around (outputting a line of code) and the child thread has grabbed the execution.
Step Two
So just the two ways we have to give business, main and sub plus synchronized.
At this point, at least two threads (parent thread Cheng Zi threads) do not interfere (mutually exclusive), but it is also possible that the parent thread runs two laps (output 20 lines of code) in other words, we let two threads mutually exclusive, but cannot coordinate the communication. (They have no alternating output!)
Step three
Class business{ Private Boolean shouldsub=true; This variable name is very good. Public synchronized void main (int j) { //j as the largest of the 50 cycles if (shouldsub) { try{ This.wait (); } catch (Exception e) {} } for (int i=1;i<=10;i++) System.out.println ("main" +i+ "of Loop" +j); Shouldsub=true; The parent thread has executed once, so Shouldsub is true for the child thread executed this.notify (); } Public synchronized void Sub (int j) { //j as the largest of the 50 cycles if (!shouldsub) { try{ this.wait (); } catch (Exception e) {} } for (int i=1;i<=5;i++) System.out.println ("sub" +i+ "of Loop" +j); Shouldsub=false; The child thread has been executed once so shouldsub to False can no longer execute this.notify ();} }
OK, here we are. Let's see if there's any room to change.
if (!shouldsub) { try{ this.wait (); } catch (Exception e) {} } should be changed to the following form while (!shouldsub) { try{ this.wait (); } catch (Exception e) {} }
Why?
Because sometimes the thread will be "false wake", with a while loop can be judged again.
In fact, after writing the code, I still think the key to the problem isabstract the business class to extract the true core of the operational logic。
One-to-face questions about threads