1、线程通信模型
- 线程间通信的模型有两种:共享内存和消息传递
2、线程通信方式一:Object.wait() 和 notify()
wait/notify注意事项
- wait/notify必须在同步代码块或者同步函数中使用
- wait/notify必须由同一个锁对象调用
- wait/notify方法属于Object的方法,所以锁对象可以是任意对象
notify之后不是表示线程立即恢复执行,因为当初中断的地方是在同步代码块中,而此刻它已经不再持有锁,它需要再去和其他线程抢锁
生产者消费者问题(Producer-consumer problem),也称有限缓冲问题(Bounded-buffer problem),是一个多线程同步问题的经典案例。生产者生成一定量的数据放到缓冲区中,然后重复此过程;与此同时,消费者也在缓冲区消耗这些数据。生产者和消费者之间必须保持同步,要保证生产者不会在缓冲区满时放入数据,消费者也不会在缓冲区空时消耗数据。
public class Main {public static void main(String[] args) throws InterruptedException {Storage storage = new Storage();Thread p1 = new Thread(new Producer(storage));Thread p2 = new Thread(new Producer(storage));Thread p3 = new Thread(new Producer(storage));Thread c1 = new Thread(new Consumer(storage));Thread c2 = new Thread(new Consumer(storage));Thread c3 = new Thread(new Consumer(storage));c1.start();c2.start();c3.start();p1.start();p2.start();p3.start();}/*** 生产者*/public static class Producer extends Thread {private Storage storage;public Producer(){}public Producer(Storage storage){this.storage = storage;}@Overridepublic void run(){while(true){try{Thread.sleep(1000);storage.produce();}catch (InterruptedException e){e.printStackTrace();}}}}/*** 消费者*/public static class Consumer extends Thread {private Storage storage;public Consumer(){}public Consumer(Storage storage){this.storage = storage;}@Overridepublic void run(){while(true){try{Thread.sleep(3000);storage.consume();}catch (InterruptedException e){e.printStackTrace();}}}}/*** 仓库类*/public static class Storage extends Thread {// 仓库容量private final int MAX_SIZE = 10;// 仓库存储的载体private LinkedList<Object> list = new LinkedList<>();public void produce() {synchronized (list) {while (list.size() + 1 > MAX_SIZE) {System.out.println("【生产者" + Thread.currentThread().getName()+ "】仓库已满");try {list.wait();} catch (InterruptedException e) {e.printStackTrace();}}list.add(new Object());System.out.println("【生产者" + Thread.currentThread().getName()+ "】生产一个产品,现库存" + list.size());list.notifyAll();}}public void consume() {synchronized (list) {while (list.size() == 0) {System.out.println("【消费者" + Thread.currentThread().getName()+ "】仓库为空");try {list.wait();} catch (InterruptedException e) {e.printStackTrace();}}list.remove();System.out.println("【消费者" + Thread.currentThread().getName()+ "】消费一个产品,现库存" + list.size());list.notifyAll();}}}}
