生产者与消费者一对一,一对多,多对多

来源:互联网 发布:分布式java应用 编辑:程序博客网 时间:2024/06/05 16:30

生产者与消费者问题涉及对象

  • 生产者
  • 消费者
  • 生产与消费对象 (以下简称目标对象,通常是通过某个容器存放如:ArrayList)

类图表示:
这里写图片描述

生产者与消费者问题主要解决的是同步问题:

  • 当目标对象已经为0,或已经不存在时,这时消费者就不能再继续消费了,所以要让生产者先生产目标对象。
  • 当目标对象达到一定数量时应停止生产了,这时生产者应停止继续生产,需要消费者先进行消费目标对象。

可知三者关系,生产者与消费者共同作用于目标对象,但生产者与消费者之间又存在先后关系。

生产者——>生成一定量的数据放到缓冲区中,然后重复此过程;
消费者——>在缓冲区消耗这些数据。
而生产者-消费者之间存在三种关系,即
生产者与生产者之间是互斥关系;
消费者与消费者之间是互斥关系;
生产者与消费者之间是同步与互斥关系。

下面直接用代码讲解:

消费者与生产者一对一:

//目标对象类

package 生产者与消费者一对一队列操作;import java.util.ArrayList;import java.util.List;public class CookieList {    public static final int MAX_SIZE = 1;     private List<String> list = new ArrayList<String>();    public synchronized void product(){        try{            if(list.size()==MAX_SIZE)                this.wait();            list.add("cookie"+((int)(Math.random()*10)+1));            System.out.println("生产者生产了"+list.get(0));            this.notify();        }catch(InterruptedException e){        }    }    public synchronized void customer(){        try{            if(list.size()==0)                this.wait();            System.out.println("消费者消费了:"+list.get(0));            list.remove(0);            this.notify();        }catch(InterruptedException e){        }    }}

Main类

package 生产者与消费者一对一队列操作;public class Main {    public static void main(String[] args) {        CookieList cookieList = new CookieList();        P p = new P(cookieList);        C c = new C(cookieList);        p.start();        c.start();    }    //生产者线程    public static class P extends Thread{        public CookieList cookieList;        public P(CookieList cookieList){            this.cookieList = cookieList;        }        @Override        public void run() {            while(true){                this.cookieList.product();                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    // TODO 自动生成的 catch 块                    e.printStackTrace();                }            }        }    }    //消费者线程    public static class C extends Thread{        public CookieList cookieList;        public C(CookieList cookieList){            this.cookieList = cookieList;        }        @Override        public void run() {            while(true){                this.cookieList.customer();                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    // TODO 自动生成的 catch 块                    e.printStackTrace();                }            }        }    }}

对于多消费或多生产需要注意的点

比如针对消费者,当需要唤醒生产者生产时可以调用notify()方法,但notify()方法并不能指定唤醒监视队列特定的线程而是随机唤醒的,当多个消费者的时候一个消费者唤醒的可能是另一个消费者线程而不是生产者线程,所以当有多个消费者或多生产者的情况下可以使用notifyAll()以防止程序出现“假死现象”(即线程全都处于阻塞状态),及需注意while(){wait()}的使用
具体请看以下代码

消费者与生产者一生产对多消费:

package 生产者与消费者一生产多消费队列操作;import java.util.ArrayList;import java.util.List;public class CookieList {    public static final int MAX_SIZE = 1;     private List<String> list = new ArrayList<String>();    public synchronized void product(){        try{            if(list.size()==MAX_SIZE)                this.wait();            list.add("cookie"+((int)(Math.random()*10)+1));            System.out.println("生产者生产了"+list.get(0));            this.notify();        }catch(InterruptedException e){        }    }    public synchronized void customer(){        try{            //注意while            while(list.size()==0)                this.wait();            System.out.println("消费者消费了:"+list.get(0));            list.remove(0);            this.notifyAll();        }catch(InterruptedException e){        }    }}

Main

package 生产者与消费者一生产多消费队列操作;public class Main {    public static void main(String[] args) {        CookieList cookieList = new CookieList();        P p = new P(cookieList);        C c = new C(cookieList);        p.start();        c.start();        for(int i=0;i<3;++i){            c  = new C(cookieList);            c.start();        }    }    //生产者线程    public static class P extends Thread{        public CookieList cookieList;        public P(CookieList cookieList){            this.cookieList = cookieList;        }        @Override        public void run() {            while(true){                this.cookieList.product();                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    // TODO 自动生成的 catch 块                    e.printStackTrace();                }            }        }    }    //消费者线程    public static class C extends Thread{        public CookieList cookieList;        public C(CookieList cookieList){            this.cookieList = cookieList;        }        @Override        public void run() {            while(true){                this.cookieList.customer();                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    // TODO 自动生成的 catch 块                    e.printStackTrace();                }            }        }    }}

消费者与生产者一消费对多生产:

package 生产者与消费者一消费多生产队列操作;import java.util.ArrayList;import java.util.List;public class CookieList {    public static final int MAX_SIZE = 1;     private List<String> list = new ArrayList<String>();    public synchronized void product(){        try{            while(list.size()==MAX_SIZE)                this.wait();            list.add("cookie"+((int)(Math.random()*10)+1));            System.out.println("生产者生产了"+list.get(0));            this.notifyAll();        }catch(InterruptedException e){        }    }    public synchronized void customer(){        try{            //注意while            if(list.size()==0)                this.wait();            System.out.println("消费者消费了:"+list.get(0));            list.remove(0);            this.notify();        }catch(InterruptedException e){        }    }}

Main

package 生产者与消费者一消费多生产队列操作;public class Main {    public static void main(String[] args) {        CookieList cookieList = new CookieList();        P p = new P(cookieList);        C c = new C(cookieList);        p.start();        c.start();        for(int i=0;i<3;++i){            p  = new P(cookieList);            p.start();        }    }    //生产者线程    public static class P extends Thread{        public CookieList cookieList;        public P(CookieList cookieList){            this.cookieList = cookieList;        }        @Override        public void run() {            while(true){                this.cookieList.product();                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    // TODO 自动生成的 catch 块                    e.printStackTrace();                }            }        }    }    //消费者线程    public static class C extends Thread{        public CookieList cookieList;        public C(CookieList cookieList){            this.cookieList = cookieList;        }        @Override        public void run() {            while(true){                this.cookieList.customer();                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    // TODO 自动生成的 catch 块                    e.printStackTrace();                }            }        }    }}

消费者与生产者多消费对多生产:

package 多生产多消费队列操作;import java.util.ArrayList;import java.util.List;public class CookieList {    public static final int MAX_SIZE = 5;     private List<String> list = new ArrayList<String>();    public synchronized void product(){        try{            while(list.size()==MAX_SIZE)                this.wait();            list.add("cookie"+((int)(Math.random()*10)+1));            System.out.println("生产者生产了"+list.get(0));            this.notifyAll();        }catch(InterruptedException e){        }    }    public synchronized void customer(){        try{            //注意while            while(list.size()==0)                this.wait();            System.out.println("消费者消费了:"+list.get(0));            list.remove(0);            this.notifyAll();        }catch(InterruptedException e){        }    }}

Main

package 多生产多消费队列操作;public class Main {    public static void main(String[] args) {        CookieList cookieList = new CookieList();        P p = new P(cookieList);        C c = new C(cookieList);        p.start();        c.start();        for(int i=0;i<3;++i){            c  = new C(cookieList);            c.start();            p  = new P(cookieList);            p.start();        }    }    //生产者线程    public static class P extends Thread{        public CookieList cookieList;        public P(CookieList cookieList){            this.cookieList = cookieList;        }        @Override        public void run() {            while(true){                this.cookieList.product();                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    // TODO 自动生成的 catch 块                    e.printStackTrace();                }            }        }    }    //消费者线程    public static class C extends Thread{        public CookieList cookieList;        public C(CookieList cookieList){            this.cookieList = cookieList;        }        @Override        public void run() {            while(true){                this.cookieList.customer();                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    // TODO 自动生成的 catch 块                    e.printStackTrace();                }            }        }    }}
原创粉丝点击