生产者线程:
如果水果的数量在[0,9]则开始生产,否则转到消费线程。
public class Producer implements Runnable { private Fruit fruit; public Producer() { super(); } public Producer(Fruit fruit) { super(); this.fruit = fruit; } public Fruit getFruit() { return fruit; } public void setFruit(Fruit fruit) { this.fruit = fruit; } @Override public void run() { // TODO Auto-generated method stub while(true){ synchronized (fruit) { //积压了10个水果未卖出去 停掉生产的线程等待卖出去 if(fruit.getNumber()>=10){ try { fruit.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(fruit.getNumber()>=0&&fruit.getNumber()<10){ try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(fruit.getName()+"被生产出来了"); fruit.setNumber(fruit.getNumber()+1); System.out.println("当前水果数量为"+fruit.getNumber()); fruit.notify(); } } } } }
消费者线程:
如果水果的数量在大于0,即可消费,否则转到生产线程
public class Customer implements Runnable { private Fruit fruit; public Customer() { super(); } public Customer(Fruit fruit) { super(); this.fruit = fruit; } public Fruit getFruit() { return fruit; } public void setFruit(Fruit fruit) { this.fruit = fruit; } @Override public void run() { while(true){ //处理并发问题 synchronized (fruit) { //判断水果的数量是否>0; if(fruit.getNumber()>0){ try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(fruit.getName()+"被买走了"); //减少水果数量 fruit.setNumber(fruit.getNumber()-1); System.out.println("当前水果数量为"+fruit.getNumber()); fruit.notify(); } else{ try { //水果已经卖完拿了 等待生产 fruit.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } }
Fruit类
public class Fruit { private int number; private String name; public Fruit() { super(); } public Fruit(int number, String name) { super(); this.number = number; this.name = name; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
当调用obj.notify()/notifyAl0()l后,调用线程依旧持有obj锁,当调用obj.wait()后,调用线程会释放obj锁,如果将synchronized (fruit)放在while(true)前面,会因为同步锁未及时释放,一直运行到obj.wait()才释放同步锁。