前提:生产者不断地生产产品,消费者取走生产者生产的产品。生产者生产出产品后将其放到一个区域之中,消费者从这个地方去除数据java
分析: 1.是否设计多线程?是,生产者,消费者 2.是否涉及到共享数据?有!考虑线程的安全 3.此共享数据是谁?即为产品的数量 4.是否设计线程的通讯?存在生产者与消费者的通讯
public class Clerk { //当前商品数量 private int product = 0; public synchronized void addProduct() {//同步控制并发 while (product >= 5) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } product++; System.out.println(Thread.currentThread().getName() + "生成了" + product + "产品"); notifyAll();//唤起全部阻塞的多线程 //notify 只能通知一个在等待的对象,其余在等待的对象不会通知,会致使多线程的并发问题 } public synchronized void consumProduce() { while (product <= 0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + "消费" + product + "产品"); product--; notifyAll(); } }
public class Consumer implements Runnable {//消费者 Clerk clerk; public Consumer(Clerk clerk){ this.clerk = clerk; } @Override public void run() { System.out.println("消费者消费产品"); while (true){ clerk.consumProduce(); } } }
public class Product implements Runnable {//生产者 Clerk clerk; public Product(Clerk clerk){ this.clerk = clerk; } @Override public void run() { System.out.println("生产者生产产品"); for(int i=0;i<10;i++){ clerk.addProduct(); } } }
多线程测试类: public class TestProductConsume { public static void main(String args[]){ Clerk clerk = new Clerk(); for(int i = 0; i < 4;i++){ Product p1 = new Product(clerk); Consumer c1 = new Consumer(clerk); Thread t1 = new Thread(p1); Thread t2 = new Thread(c1); t1.setName("生产者"+i); t2.setName("消费者"+i); t1.start(); t2.start(); } } }
notify只会通知一个在等待的对象,而notifyAll会通知全部在等待的对象,而且全部对象都会继续运行安全
被wait的线程,想要继续进行的话,必须知足2个条件:多线程
1.通过有其余线程notify或notifyAll,而且当前线程被通知到并发
2.通过和其余线程进行锁竞争,成功获取锁ide
notify 仅仅通知一个线程,而且咱们不知道哪一个线程会收到通知,然而 notifyAll 会通知全部等待中的线程。换言之,若是只有一个线程在等待一个信号灯,notify和notifyAll都会通知到这个线程。但若是多个线程在等待这个信号灯,那么notify只会通知到其中一个,而其它线程并不会收到任何通知,而notifyAll会唤醒全部等待中的线程。测试