One, the communication between the threads
Instance code:
Requirement is: After entering a name and gender, a name and gender will be output
class resource{string name; String sex;} Class Input implements Runnable{resource R;input (Resource r) {THIS.R = R;} public void Run () {int x = 0;while (True) {synchronized (R) {if (x==0) {r.name = "BLF"; r.sex = "Male";} else {r.name = "Nininini"; r.sex = "female";} x = (++x)%2;}}} Class output implements Runnable{resource r;public output (Resource r) {//TODO auto-generated constructor STUBTHIS.R = r;} public void Run () {while (true) {synchronized (R)///input and output are all applied with the same lock {System.out.println (r.name+ "..." +r.sex);}}} public class Main {public static void main (string[] args) {Resource r = new Resource ();//share the same resource input in = new input (r); OUTP UT out = new Output (r); thread T1 = new thread (in); Thread t2 = new Thread (out); T1.start (); T2.start ();}}
Although the above code resolves, multithreading the same resource problem, but there is a problem is that printing a lot of people and gender and then print another, unable to achieve alternating output, reason: The input thread gets execution, does not execute once, enter the name and gender, the input thread also has the executive right, has been assigned value , wait until after switching to output execution, output the last name and gender, but the output thread will not output only once and always output, so there are many problems printing the same name and gender
Second, the thread's wait/wake mechanism:
Use a Boolean value to determine if there is data, there is no place, no
When the input thread executes, it determines whether there is data, has, releases execution, releases execution, enters a frozen state, outputs a thread execution, and outputs a Boolean value of false.
Input: if (flag)//value wait ();//current freeze, toggle output thread flag = true; Notify (); Output: if (!flag) wait (); Flag = False;//flag false, Output complete notify ();//wake-up input thread
Wait/wake mechanism:
Method:
1.wait ();//causes the thread to enter a frozen state, the CPU releases execution and execution eligibility, the thread that is wait () is stored in the thread pool 2.notify ();//wakes any thread in the thread pool 3.notifyAll ();//Wakes All threads, To be in a running state or temporarily blocked state, in short, to make it eligible for execution
These methods must be defined in synchronization, which are methods used to manipulate the state of the thread, so it is important to be clear on which locked thread
(Wait () a locks the thread that can only be used to wake the A-lock thread with the notify of a lock. )
Understand: And wait () methods are defined in the object class, these methods are the method of the monitor, and the monitor, it can be understood as a lock, control which locks under the thread, and the lock can be arbitrary, and all classes are inherited from the object class, so wait () Class is defined in object
The following code solves the problem of the above code and implements the alternating execution of the input and output threads.
Class Resource extends object{string name; String sex; Boolean flag = false;} Class Input implements Runnable{resource R;input (Resource r) {THIS.R = R;} public void Run () {int x = 0;while (True) {synchronized (R) {if (R.flag) {try {r.wait ();} catch (Exception e) {//Todo:handle Exception}}if (x==0) {r.name = "BLF"; r.sex = "Male";} else {r.name = "Nininini"; r.sex = "female";} R.flag = True;r.notify (); x = (++x)%2;}}} Class output implements Runnable{resource r;public output (Resource r) {//TODO auto-generated constructor STUBTHIS.R = r;} public void Run () {if (true) {synchronized (R) {if (!r.flag) {try {r.wait ()} catch (Exception e) {//Todo:handle exceptio N}}system.out.println (r.name+ "..." +r.sex); R.flag = False;r.notify ();}}} public class Main {public static void main (string[] args) {Resource r = new Resource (), Input in = new input (r), Output out = New Output (R); thread T1 = new thread (in); Thread t2 = new Thread (out); T1.start (); T2.start ();}}
Three:
wait for Wake mechanism code optimization
Members of a resource should be private and provide methods for control.
So the synchronous operation is performed in the resource class, and the synchronization function is applied
Class Resource extends Object{private string name;private string sex;p rivate Boolean flag = false;public synchronized Voi D Set (String name,string Sex) {//TODO auto-generated constructor stubif (flag) {try {this.wait ()} catch (Exception e) {// Todo:handle exception}}this.name = Name;this.sex = Sex;flag = True;this.notify ();} Public synchronized void out () {if (!flag) {try {this.wait ();} catch (Exception e) {//Todo:handle Exception}system.out.pri Ntln (name+ ":" +sex); flag = False;this.notify ();}}} Class Input implements Runnable{resource R;input (Resource r) {THIS.R = R;} public void Run () {int x = 0;while (True) {if (x==0) {r.set ("BLF", "Male");} else {r.set ("Nininini", "female");} x = (++x)%2;}}} Class output implements Runnable{resource r;public output (Resource r) {//TODO auto-generated constructor STUBTHIS.R = r;} public void Run () {while (true) {R.out ()}}} public class Main {public static void main (string[] args) {Resource r = new Resource (), Input in = new input (r), Output out = New Output (R); Thread T1 = new Thread (in); Thread t2 = new Thread (out); T1.start (); T2.start ();}}
Java Learning Lesson 26th (Multithreading (v))-communication issues between multiple threads