生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。
public class TestProduct { public static void main(String[] args) { Clerk01 clerk01 = new Clerk01(); Thread pro = new Thread(new Productor01(clerk01)); Thread con = new Thread(new Consumer01(clerk01)); pro.start(); con.start(); } } //销售员 class Clerk01 { private int product = 0; //生产商品 public synchronized void add() { if (product >= 20) { try { wait(); System.out.println("请暂停生产!"); } catch (InterruptedException e) { e.printStackTrace(); } }else{ product++; System.out.println("生产者生产了第"+product+"个商品!"); notifyAll(); } } //消费商品 public synchronized void remove(){ if (this.product <= 0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } }else{ System.out.println("顾客取走了第"+ product +"个商品"); product--; notifyAll(); } } } //生产者 class Productor01 implements Runnable { Clerk01 clerk01; public Productor01(Clerk01 clerk01){ this.clerk01 = clerk01; } @Override public void run() { // System.out.println("货架空了!"); System.out.println("现在开始生产产品"); while(true){ try { Thread.sleep((int)(Math.random()*2000)); } catch (InterruptedException e) { } clerk01.add(); } } } //消费者 class Consumer01 implements Runnable { Clerk01 clerk01; public Consumer01(Clerk01 clerk01){ this.clerk01 = clerk01; } @Override public void run() { System.out.println("消费者开始取产品"); while(true){ try { Thread.sleep((int)(Math.random()*2000)); } catch (InterruptedException e) { } clerk01.remove(); } } }
synchronized关键字,代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、D等)正在用这个方法,若有则要等正在使用synchronized方法的线程B(或者C、D)运行完这个方法后再运行此线程A,若没有则直接运行。
wait() 方法是等待的意思,在lang包中,所以不需要导包等可以直接调用。它与 notify() 和 notifyAll() 这两个方法往往同时存在,这两个方法用来唤醒wait()的等待,其中这两种唤醒方法的区别大家应该都知道,末尾的All 就说明了一切。接下来我们进行详细的区别解释。
notify他只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对
象notify的线程们,当第一个线程运行完毕以后释放对象上的锁,此时如果该对象没有再次使用notify语句,
即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这
个对象发出一个notify或notifyAll,它们等待的是被notify或notifyAll,而不是锁。