[Java] [Multithreading] Communication between two threads, wait, notify, notifyAll

Waiting for wake-up mechanism: wait(), notify()

1. When do you need to communicate?

  • When multiple threads execute concurrently, the CPU switches threads randomly by default
  • If we want them to execute regularly, we can use communication, such as printing once per thread, taking turns

2. How to communicate

  • If you want the thread to wait, call wait()
  • If you want to wake up the waiting thread, call notify();
  • These two methods must be executed in synchronized code and called using the synchronization lock object, this
public class Demo1_Notify {
	/**
	 * @param args
	 * Wait for the wake-up mechanism
	 */
	public static void main(String[] args) {
		final Printer p = new Printer();
		
		new Thread() { //Thread 1
			public void run() {
				while(true) {
					try {
						p.print1();
					} catch (InterruptedException e) {
						
						e.printStackTrace ();
					}
				}
			}
		}.start();
		
		new Thread() { //Thread 2
			public void run() {
				while(true) {
					try {
						p.print2();
					} catch (InterruptedException e) {
						
						e.printStackTrace ();
					}
				}
			}
		}.start();
	}
}

//Wait for the wake-up mechanism
class Printer {
	private int flag = 1;
	public void print1() throws InterruptedException {							
		synchronized(this) {
			if(flag != 1) {
				this.wait(); //The current thread waits until it is woken up
			}
			System.out.print("黑");
			System.out.print("马");
			System.out.print("程");
			System.out.print("序");
			System.out.print("员");
			System.out.print("\r\n");
			flag = 2;
			this.notify(); //Wake up a single waiting thread randomly, and still have the right to execute at this time, which makes the thread enter the waiting
		}
	}
	
	public void print2() throws InterruptedException {
		synchronized(this) {
			if(flag != 2) {
				this.wait();
			}
			System.out.print("传");
			System.out.print("智");
			System.out.print("播");
			System.out.print("客");
			System.out.print("\r\n");
			flag = 1;
			this.notify();
		}
	}
}

2. The problem of multiple thread communication

  • The notify() method is to randomly wake up a thread
  • notifyAll() method is to wake up all threads
  • The specified thread cannot be woken up before JDK5
  • If there is communication between multiple threads, you need to use notifyAll() to notify all threads, and use while to repeatedly judge the conditions
public class Demo2_NotifyAll {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		final Printer2 p = new Printer2();
		new Thread() {
			public void run() {
				while(true) {
					try {
						p.print1();
					} catch (InterruptedException e) {
						e.printStackTrace ();
					}
				}
			}
		}.start();
		
		new Thread() {
			public void run() {
				while(true) {
					try {
						p.print2();
					} catch (InterruptedException e) {	
						e.printStackTrace ();
					}
				}
			}
		}.start();
		
		new Thread() {
			public void run() {
				while(true) {
					try {
						p.print3();
					} catch (InterruptedException e) {						
						e.printStackTrace ();
					}
				}
			}
		}.start();
	}
}

class Printer2 {
	private int flag = 1;
	public void print1() throws InterruptedException {							
		synchronized(this) {
			while(flag != 1) {
				this.wait(); //The current thread is waiting
			}
			System.out.print("黑");
			System.out.print("马");
			System.out.print("程");
			System.out.print("序");
			System.out.print("员");
			System.out.print("\r\n");
			flag = 2;
			//this.notify(); //Randomly wake up a single waiting thread
			this.notifyAll();
		}
	}
	
	public void print2() throws InterruptedException {
		synchronized(this) {
			while(flag != 2) {
				this.wait(); //Thread 2 is waiting here
			}
			System.out.print("传");
			System.out.print("智");
			System.out.print("播");
			System.out.print("客");
			System.out.print("\r\n");
			flag = 3;
			//this.notify();
			this.notifyAll();
		}
	}
	
	public void print3() throws InterruptedException {
		synchronized(this) {
			while(flag != 3) {
				this.wait(); //Thread 3 is waiting here, where the if statement is waiting, where it is
						//The while loop is a loop judgment, and the mark will be judged each time
			}
			System.out.print("i");
			System.out.print("t");
			System.out.print("h");
			System.out.print("e");
			System.out.print("i");
			System.out.print("m");
			System.out.print("a");
			System.out.print("\r\n");
			flag = 1;
			//this.notify();
			this.notifyAll();
		}
	}
}

3. Common usage of wait() and notify()

In Java multi-threaded development, we often use the wait() and notify() methods to achieve cooperation between threads. Simply speaking, the steps are as follows: 
1. Thread A acquires the lock, executes wait(), and releases the lock; 
2. Thread B acquires the lock lock, execute notify() after completing the business, and then release the lock; 
3. After thread B releases the lock, thread A acquires the lock and continues to execute the code after wait();

Notice:wait(long timeout): Let the current thread be in a "waiting (blocking) state", "until other threads call the notify() method or  notifyAll()  method of this object, or exceed the specified amount of time ", the current thread is woken up (entered "ready state").


Fourth, the communication needs to pay attention to the following points:

1. In the synchronization code block, which object is used to lock, which object is used to call the wait method: this.wait()

2. Why are the wait method and the notify method defined in the Object class?

Because the lock object can be any object, Object is the base class of all classes, so the wait method and the notify method need to be defined in the Object class



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324521036&siteId=291194637