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(); } }