zoukankan      html  css  js  c++  java
  • 多生产者多消费者问题

    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()

  • 相关阅读:
    整型变量修饰符,char类型数据存储原理,字节数,
    进制
    C语言的数据、常量和变量
    递归函数
    函数,#include <>和#include " "区别
    分支语句
    hdu_1015(dfs)
    基本数论
    基础几何
    hdu_1018(斯大林公式/n!的位数)
  • 原文地址:https://www.cnblogs.com/xurui1995/p/5228702.html
Copyright © 2011-2022 走看看