多生产者多消费者问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多生产者多消费者问题相关的知识,希望对你有一定的参考价值。
1单生产者单消费者
package example; class Resource{ private String name; private int num=1; private boolean flag=false; public synchronized void set(String name){ if(flag){ try { wait(); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } this.name=name+num; num++; System.out.println(Thread.currentThread().getName()+"生产"+this.name); flag=true; notify(); } public synchronized void out(){ if(!flag){ try { wait(); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } System.out.println(Thread.currentThread().getName()+"消费"+this.name); flag=false; notify(); } } class Producer implements Runnable{ private Resource r; Producer(Resource r){ this.r=r; } public void run() { while(true){ r.set("面包"); } } } class Consumer implements Runnable{ private Resource r; Consumer(Resource r){ this.r=r; } public void run() { while(true){ r.out(); } } } public class Test{ public static void main(String[] args) { Resource r=new Resource(); Producer pro=new Producer(r); Consumer con=new Consumer(r); Thread t1=new Thread(pro); Thread t2=new Thread(con); t1.start(); t2.start(); } }
Thread-0生产面包1
Thread-1消费面包1
Thread-0生产面包2
Thread-1消费面包2
Thread-0生产面包3
Thread-1消费面包3
Thread-0生产面包4
Thread-1消费面包4
Thread-0生产面包5
Thread-1消费面包5
Thread-0生产面包6
Thread-1消费面包6
Thread-0生产面包7
Thread-1消费面包7
Thread-0生产面包8
Thread-1消费面包8
Thread-0生产面包9
Thread-1消费面包9
Thread-0生产面包10
Thread-1消费面包10
Thread-0生产面包11
.........................
2多生产者与多消费者模式
package example; class Resource{ private String name; private int num=1; private boolean flag=false; public synchronized void set(String name){ while(flag){ try { wait(); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } this.name=name+num; num++; System.out.println(Thread.currentThread().getName()+"生产"+this.name); flag=true; notifyAll(); } public synchronized void out(){ while(!flag){ //改if为while try { wait(); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } System.out.println(Thread.currentThread().getName()+"消费"+this.name); flag=false; notifyAll(); //变为notifyAll() } } class Producer implements Runnable{ private Resource r; Producer(Resource r){ this.r=r; } public void run() { while(true){ r.set("面包"); } } } class Consumer implements Runnable{ private Resource r; Consumer(Resource r){ this.r=r; } public void run() { while(true){ r.out(); } } } public class Test{ public static void main(String[] args) { Resource r=new Resource(); Producer pro=new Producer(r); Consumer con=new Consumer(r); Thread t1=new Thread(pro); Thread t2=new Thread(pro); Thread t3=new Thread(con); Thread t4=new Thread(con); t1.start(); t2.start(); t3.start(); t4.start(); } }
在这里我们做了两处改动,原因主要有2点。
1.如果任然用if和notify()会存在安全问题
public synchronized void set(String name){ if(flag){ //2,t0再次取得执行权,判断后wait(),接着生产线程t1获得执行权,判断后wait() try { wait(); //6,T0拿到执行权,并生产面包2,唤醒t2,释放锁 } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } this.name=name+num; num++; System.out.println(Thread.currentThread().getName()+"生产"+this.name); //1,生产线程t0生产面包1,置flag为true flag=true; notify(); } public synchronized void out(){ if(!flag){ //5消费线程t3取得执行权和锁,wait(),释放锁 try { wait(); //7,t2醒来,并消费面包2,唤醒t3,t3又消费面包2 } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } System.out.println(Thread.currentThread().getName()+"消费"+this.name); //3消费线程t2取得执行权,消费t1 flag=false; notify(); //4唤醒t0,但t0还没有锁,flag=false; }
最大问题是用if(),线程醒来后不用再判断flag了所以该用while
2如果用while加notify(),可能会造成死锁。所以用notifyAll()
以上是关于多生产者多消费者问题的主要内容,如果未能解决你的问题,请参考以下文章