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的话,容易出现唤醒本方线程的情况,导致两方线程都处于等待中
时间: 2024-10-31 03:24:39