package 多线程;public class PandC { public static void main(String[] args) {// Producer p= new Producer();// Consumer c = new Consumer();// new Thread(p,"生产者").start();// new Thread(p,"生产者").start();// new Thread(c,"消费者").start();// new Thread(c,"消费者").start(); new Thread(new Producer(),"生产者").start(); new Thread(new Consumer(),"消费者").start(); new Thread(new Producer(),"生产者").start(); new Thread(new Consumer(),"消费者").start(); }}//通过单例模式 保证资源唯一//class Resource{// private String name;// private int count;// private boolean flag=false;// static Resource r = new Resource();// private Resource() {// }// public static Resource getRes(){// return r;// }// public synchronized void produce(String name){// if(!flag)// try {// wait();//this.wait(); //this可省略// } catch (InterruptedException e) {// // TODO Auto-generated catch block// e.printStackTrace();// }// name = name+count++;// flag=false;// System.out.println(Thread.currentThread().getName()+" .........生产商品:"+count);// this.notify();//this可省略// }// public synchronized void consume(){// if(flag)// try {// wait();// } catch (InterruptedException e) {// // TODO Auto-generated catch block// e.printStackTrace();// }// flag=true;// System.out.println(Thread.currentThread().getName()+" ======消费商品:"+count);// notify();// }//}class Producer implements Runnable{ Resource r = Resource.getRes(); @Override public void run() { while(true) r.produce("商品:"); }}class Consumer implements Runnable{ Resource r = Resource.getRes(); @Override public void run() { while(true) r.consume(); }}/* 输出: 生产一个 被消费两次 生产者 .........生产商品:44500消费者 ======消费商品:44500消费者 ======消费商品:44500生产者 .........生产商品:44501消费者 ======消费商品:44501消费者 ======消费商品:44501 生产两个 却只被消费一个生产者 .........生产商品:45841生产者 .........生产商品:45842消费者 ======消费商品:45842生产者 .........生产商品:45843消费者 ======消费商品:45843 * 解决办法 每次线程被唤醒 都去判断一次flag 并 需要唤醒所有线程 否则会出现所有线程全部等待 代码:*/ class Resource{ private String name; private int count; private boolean flag=false; static Resource r = new Resource(); private Resource() { } public static Resource getRes(){ return r; } public synchronized void produce(String name){ while(!flag) try { wait();//this.wait(); //this可省略 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } name = name+count++; flag=false; System.out.println(Thread.currentThread().getName()+" .........生产商品:"+count); this.notifyAll();//this可省略 } public synchronized void consume(){ while(flag) try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } flag=true; System.out.println(Thread.currentThread().getName()+" ======消费商品:"+count); notifyAll(); }}
对于多个生产者和消费者
为什么要定义while判断标记??
原因:让被唤醒的线程,再一次判断标记
为什么定义notifyAll
原因:要唤醒对方线程,要唤醒对方线程只能通过唤醒同一锁上的所有线程
如果值用notify的话,容易出现唤醒本方线程的情况,导致两方线程都处于等待中