The theory of

When a thread calls the WAIT method, it must hold the lock on the object being called. After the wait method is called, the lock is releasedCopy the code
public static void main(String[] args) throws InterruptedException { Object obj = new Object(); / / an error Java. Lang. IllegalMonitorStateException / / call an object's wait (), the object must be lock / / obj. Wait (); // After compiling to bytecode, Monitorenter // Monitorexit (both normal and abnormal exit) //obj.wait() will also correspond to monitorexit when synchronized is implemented Monitorexit directive synchronized(obj) {// Correct // to hold the lock before // release the lock obj.wait(); }Copy the code
After invoking wait, the state can be exited only in one of four ways: 1. When a thread calls notify of the current lock object And happened to wake up is the thread (the place to explain why is happened to: because the lock object may be a number of threads to use lock, when a thread calls the lock wait method of the object is to put the thread in the waiting queue of lock object, so there may be many in the queue waiting for the thread, then notify only calls Wake up. When a thread calls notifyAll 3 of the current lock object. 4. Wait time timed out (if wait time is set)Copy the code

conclusion

1. Before invoking the WAIT method, ensure that the thread that invoked the wait method holds the object lock 2. When the wait method is called, the thread that called the wait method releases the lock and enters the wait state 3. When the thread enters the wait state, it can wait for another thread to call notify or notifyAll on the lock. Once awakened, it will compete fairly with other threads for locks. 5. Calling a wait method should be placed in a synchronized block or method. When an object's notify method is called, it wakes up a random thread in the object's wait queue, which then compets fairly with other threads for the lock 7. When an object's notify method is called, it wakes up all the threads in the object's wait queue, which then compete fairly with other threads for the lock 8. A thread holds the lock after a certain pointCopy the code

Code sample

The target

Write a multithreaded program to achieve such a goal: 1. There is an object that has a member variable counter of type int that starts with 0. 2. Create two threads, one of which increments the object's member variable counter by one and the other increments the object's member variable by one. 3. Prints the value of the object's member variable counter after each change. 4. The final output is 10101010101......Copy the code

implementation



public class MyObject {
	
	private int counter;
	
	public synchronized void inc(a) {
		//if(counter ! = 0) {
		while(counter ! =0) {
			try {
				wait();
			} catch (Exception e) {
			}
		}
		
		counter++;
		System.out.println(counter);
        
		//notify();
		notifyAll();
		
	}
	
	public synchronized void dec(a) {
		//if(counter == 0) {
		while(counter == 0) {
			try {
				wait();
			} catch (Exception e) {
			}
		}
		counter--;
		System.out.println(counter);
        
        //notify();notifyAll(); }}public class IncThread extends Thread {
	
	private MyObject myObject;
	
	public IncThread(MyObject myObject) {
		this.myObject = myObject;
	}
	
	@Override
	public void run(a) {
		for(int a=0; a<30; a++) {
			try {
				Thread.sleep((long) Math.random() * 1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch blocke.printStackTrace(); } myObject.inc(); }}}public class DecThread extends Thread {
	private MyObject myObject;
	public DecThread(MyObject myObject) {
		this.myObject = myObject;
	}

	@Override
	public void run(a) {
		for(int a=0; a<30; a++) {
			try {
				Thread.sleep((long) Math.random() * 1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch blocke.printStackTrace(); } myObject.dec(); }}}public class Client {
	
	public static void main(String[] args) {
		MyObject myObject = new MyObject();
		
		Thread incthread = new IncThread(myObject);
		
		Thread decThread = new DecThread(myObject);
		
		Thread incthread1 = new IncThread(myObject);
		
		Thread decThread1 = newDecThread(myObject); incthread.start(); decThread.start(); incthread1.start(); decThread1.start(); }}Copy the code