Object提供了三个方法wait(), notify(), notifyAll()在线程之间进行通信,以此来解决线程间执行顺序等问题。

  • wait():释放当前线程的同步监视控制器,并让当前线程进入阻塞状态,直到别的线程发出notify将该线程唤醒。
  • notify():唤醒在等待控制监视器的其中一个线程(随机)。只有当前线程释放了同步监视器锁(调用wait)之后,被唤醒的线程才有机会执行。
  • notifyAll():与上面notify的区别是同时唤醒多个等待线程。

这里补一张思想草图:
生产者与消费者之间的线程通信案例_仓库
定义一个仓库类、生产者类、消费者类、定义一个测试类来实现线程通信
仓库类

public class WareHouse {
	int product = 20;// 初值

	// 生产
	public synchronized void addProduct() {// 同步方法,一次只允许一个线程进来
		if (product >= 20) {// 当产品大于等于20时不生产

			try {
				wait();// 生产完了就等一下
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} else {// 小于20 的时候就生产商品
			product++;
			System.out.println(Thread.currentThread().getName() + "生产商品,商品数量:" + product);
			notify();// 唤醒生产者
		}
	}

	// 消费
	public synchronized void deleteProduct() {
		if (product <= 0) {// 当产品小于等于0时停止消费
			try {
				wait();// 没有买的了就要等一下
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} else {// 大于0的时候就可以消费了
			System.out.println(Thread.currentThread().getName() + "消费商品,商品数量:" + product);
			product--;
			notify();// 唤醒消费者
		}
	}

}

消费者类

public class Customer implements Runnable {
	WareHouse house;// 创建一个house

	public Customer(WareHouse house) {
		this.house = house;
	}

	@Override
	public void run() {// 重写run方法实现操作
		while (true) {
			System.out.println("消费者消费产品:");
			try {
				Thread.sleep(100);// 一个消费者购买后休息0.1s
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			house.deleteProduct();// 消费
		}
	}
}

生产者类

public class Producer implements Runnable {
	WareHouse house;

	public Producer(WareHouse house) {
		this.house = house;
	}

	@Override
	public void run() {
		while (true) {
			System.out.println("生产者生产产品:");
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			house.addProduct();// 生产
		}
	}
}

测试类

package com.yzy.thread;

/**
 * @className TestWareHouse.java
 * @author yangsir
 * @version V1.0
 * @date 2019年8月13日-下午4:28:31
 * @description
 *
 */
public class TestWareHouse {
	public static void main(String[] args) {
		// 创建一个仓库,将仓库给消费者跟生产者
		WareHouse h = new WareHouse();
		Customer c = new Customer(h);
		Producer p = new Producer(h);
		// 调用父类的有参构造,传入生产与消费者,并改名
		Thread t1 = new Thread(c, "消费者1");
		Thread t2 = new Thread(p, "生产者1");
		Thread t3 = new Thread(p, "生产者2");

		t1.start();
		t2.start();
		t3.start();

	}
}