wait,notify understanding in multithreading

First: Conceptuality

1. The wait () and notify() methods must be executed in synchronized blocks. Otherwise, it does not make sense to call wait () and notify() methods to gain lock control.

2. The difference between wait() and sleep () is that the thread calls wait() method to release the lock, runs other threads to occupy the lock, and enters the waiting queue itself.

sleep () is a temporary dormancy and does not release the lock.

3. The Notif method wakes up the first thread in the waiting queue without notifying the higher priority. Wakened processes compete equally with other threads for cpu resources

2. Case study

package thread;

class Res{
    public boolean flag = true;
    public String name;
    
}

class inputThread extends Thread{
     public Res res;
     public inputThread(Res res) {
        this.res=res;
    }
    @Override
    public  void run() {
      System.out.println("I'm writing");
      int count=0; 
      while (true) {
          synchronized (res) {
               if (res.flag) {
              try {
                res.wait();  
              	} catch (InterruptedException e) {
                e.printStackTrace();
              	}
               }
                if (count==0) {
                	System.out.println("Write in lucy");
                    res.name="lucy";   
                }else {
                	System.out.println("Write in jack");
                    res.name="Jack";
                }
                count =(count+1)%2;
                res.flag=true;  
                res.notify();
        }
    }
    }
}

class readThread extends Thread{
    public Res res;
    public readThread(Res res) {
        this.res=res;
    }
    
    @Override
    public void run() {
        while (true) {    
        synchronized (res) {
               if(!res.flag){
                 try {
                    res.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }    
               }
               System.out.println("read"+res.name);

               res.flag=false;
               res.notify();
               
            }
        }        
    }
}

public class ConmunicatThreadTest {
    //Open the thread main thread under two threads and the two user threads have random CPUs

    public static void main(String[] args) {
        Res res = new Res();
    inputThread inputThread = new inputThread(res);
    readThread  readThread = new readThread(res);
    inputThread.start();
    readThread.start();
    
    }  
       
    
}

  

1. Initial value flag=true, the writing process grabs the lock and starts to enter the synchronized code block, because flag is true at this time, execute wait() method, release the lock in hand, then the writing process grabs the lock because flag=true at this time, so it does not execute wait() to start reading directly. At this point, the lock is released because no write operation is performed, so naturally the value is not fetched, so it is read as null.

2. Continue to execute res.flag=false;res.notify() sequentially after the read operation is completed; because this is a while loop, it will continue to execute the code block in while, and then flag status as flase will enter the write operation module, after the data is written, execute res.flag=true; res.notify(); when it enters the loop statement again, it will persist. Line wait (), release the lock in your hand, wake up the reader thread,

3. Read threads get cpu resources, because flag=true. At this time, so talk about content output, continue to perform the above operations continue to write.... Read and write... read

Third, wait releases the lock and uses notify to wake it up. It can grab resources fairly with other threads. But he's not going to get it. Take a chestnut

package thread;

public class RunA  implements Runnable{

	private Object lock;

	public RunA(Object lock) {
		this.lock = lock;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		synchronized (lock){
			  try  {
				   System.out.println("A begin");
				  // lock.wait(); // Always wait, never execute
				   lock.wait(2000);// After waiting for 2 seconds, continue executing
				   System.out.println("A end");
			  } catch (InterruptedException e) {
				  e.printStackTrace();
			  }
		  }


	}
 
}
package thread;

public class RunB implements Runnable {
	private Object lock;

	public RunB(Object lock) {
		this.lock = lock;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		synchronized (lock) {
			System.out.println("b come");
			while (true) {
			}
		}
	}
	

}
package thread;

public class TestRunAandB {
	public static void main(String args[]) throws InterruptedException{
		Object lock = new Object();
		Thread threadA = new Thread(new RunA(lock));
		threadA.start();
		/*threadA.wait();
		Thread.sleep(1000);*/
		Thread.sleep(1000);
		Thread threadB = new Thread(new RunB(lock));
		threadB.start();	
	}
	

}

After A thread grabs resources, it first outputs A begin and waits for 2S. A thread is awakened, but no lock is grabbed, so it does not output A end.

 

Added by CreativeWebDsign on Fri, 06 Sep 2019 12:53:22 +0300