经典例题:生产者/消费者问题
生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处 取走产品,店员一次只能持有固定数量的产品(比如:20),如果生产者试图 生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通 知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如 果店中有产品了再通知消费者来取走产品。
分析:这里可能出现两个问题:
生产者比消费者快时,消费者会漏掉一些数据没有取到。
消费者比生产者快时,消费者会取相同的数据。
- 多线程问题,生产者线程、消费者线程
- 产品数量是共享数据
- 线程的安全
- 线程的通信
代码示例
Product.java
publicclassProduct { //产品数量privateintproductNumber=0; //生产产品publicsynchronizedvoidproduceProduct(){ if(productNumber<20){ productNumber++; System.out.println(Thread.currentThread().getName()+"正在生产第"+productNumber+"个产品"); notify(); }else{ try { wait(); } catch (InterruptedExceptione) { e.printStackTrace(); } } } //消费产品publicsynchronizedvoidconsumerProduct(){ if(productNumber>0){ System.out.println(Thread.currentThread().getName()+"正在消费第"+productNumber+"个产品"); productNumber--; notify(); }else{ try { wait(); } catch (InterruptedExceptione) { e.printStackTrace(); } } } }
Productor.java
publicclassProductorextendsThread{ privateProductproduct; publicProductor(Productproduct){ this.product=product; } publicvoidrun() { System.out.println(getName()+"生产产品......."); while(true){ try { Thread.sleep(100); } catch (InterruptedExceptione) { e.printStackTrace(); } product.produceProduct(); } } }
Consumer.java
publicclassConsumerextendsThread{ privateProductproduct; publicConsumer(Productproduct) { this.product=product; } publicvoidrun() { System.out.println(currentThread().getName()+"消费产品......."); while(true){ try { Thread.sleep(100); } catch (InterruptedExceptione) { e.printStackTrace(); } product.consumerProduct(); } } }
Test.java
publicclassTest { publicstaticvoidmain(String[] args) { Productproduct=newProduct(); Productorproductor=newProductor(product); productor.setName("生产者"); Consumerconsumer=newConsumer(product); consumer.setName("消费者"); productor.start(); consumer.start(); } }
输出:
消费者消费产品…
生产者生产产品…
生产者正在生产第1个产品
生产者正在生产第2个产品
消费者正在消费第2个产品
生产者正在生产第2个产品
消费者正在消费第2个产品
生产者正在生产第2个产品
消费者正在消费第2个产品
消费者正在消费第1个产品
生产者正在生产第1个产品
消费者正在消费第1个产品
生产者正在生产第1个产品
消费者正在消费第1个产品
生产者正在生产第1个产品
生产者正在生产第2个产品
消费者正在消费第2个产品
生产者正在生产第2个产品