zoukankan      html  css  js  c++  java
  • 生产者模式实现总结2

    第二种方法摘自:think in java

    下面我们简化一下这个例子。以Think in Java中的例子为原形。大致是这样的,我们将生产者看成是餐厅里的厨师,消费者看成是餐厅里的服务员。厨师会不停的做出食物,而服务员会将厨师做出的食 物拿给顾客。刚开始服务员是处于等待阶段,直到厨师将食物做出来后,他会通知服务员将食物拿走。这时厨师会处于等待阶段,直到服务员将食物拿走后,他会通 知厨师可以继续生产食物。下面是这个例子的代码:

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    public class Restaurant {
        Meal meal;
        ExecutorService exec = Executors.newCachedThreadPool();
        WaitPerson waitPerson = new WaitPerson(this);
        Chef chef = new Chef(this);
    
        class Meal {
            private final int orderNum;
    
            public Meal(int orderNum) {
                this.orderNum = orderNum;
    
            }
    
            public String toString() {
                return "Meal" + orderNum;
            }
        }
    
        class Chef implements Runnable {
            private Restaurant restaurant;
            private int count;
    
            public Chef(Restaurant r) {
                restaurant = r;
            }
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    while (!Thread.interrupted()) {
                        // 获取自己本身的对象锁
                        synchronized (this) {
                            // 如果restaurant中的meal不为空,继续等待
                            while (restaurant.meal != null) {
                                wait();// waiter等待meal不为空
                            }
                        }
                        System.out.println(count);
                        if(++count==10)
                        {
                            System.out.println("out of food,closing");
                            restaurant.exec.shutdownNow();//停止线程
                        }
                        System.out.println("order up");
                        // 获得chef的对象锁,以便于通知chef及时执行操作
                        synchronized (restaurant.waitPerson) {
                            restaurant.meal=new Meal(count);
                            restaurant.waitPerson.notifyAll();
    
                        }
                    }
    
                } catch (InterruptedException e) {
    
                }
            }
        }
    
        class WaitPerson implements Runnable {
            private Restaurant restaurant;
    
            public WaitPerson(Restaurant r) {
                restaurant = r;
            }
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    while (!Thread.interrupted()) {
                        // 获取自己本身的对象锁
                        synchronized (this) {
                            // 如果restaurant中的meal为空,循环执行
                            while (restaurant.meal == null) {
                                wait();// waiter等待meal不为空
                            }
                        }
                        System.out.println("WaitPerson got  " + restaurant.meal);
                        // 获得chef的对象锁,以便于通知chef及时执行操作
                        synchronized (restaurant.chef) {
                            restaurant.meal = null;// 取走meal
                            restaurant.chef.notifyAll();// 通知chef可以制造meal
    
                        }
                        TimeUnit.MILLISECONDS.sleep(100);
                    }
                } catch (InterruptedException e) {
    
                }
    
            }
        }
        Restaurant()
        {
            exec.execute(chef);
            exec.execute(waitPerson);
        }
        
        public static void main(String[] args)
        {
            new Restaurant();
        
        }
    
    }


    在这个例子中,并没有用到共享内存(Restaurant)中的同步方法,而是通过在共享内存中获取各个线程的引用,并通过它们加锁后然后相互进行通知,这里使用到了“点对点”通知的方法,即生产者只通知消费者,而不会额外去通知其它生产者。

    问题:

    在上面的方式显然不太适合多生产者-仓库-多消费者这种模式,这也是它的弊端所在。而在上篇文章介绍的第一种方法里,可以利用共享内存的同步方法,对多个生产者和消费者进行同步!但是这些方法始终都有一个问题,那就是制作效率不高,在同步方法里面,每一时刻只能有一个方法在运行,不能起到多个生产者或多个消费者同时运行,增加“生产能力”/“消费能力”;

    备注:

    这种方式在java里实现是有些稍显笨拙;在think in java中还介绍了一种生产者-消费者队列(BlockingQueue)的的方法。在这个队列中,可以放入“产品”,如果队列中没有产品,消费者去“消费”的话会自动挂起消费者,知道队列中加入了新的“商品”;

  • 相关阅读:
    (PHP)redis Zset(有序集合 sorted set)操作
    (PHP)redis Set(集合)操作
    (PHP)redis Hash(哈希)操作
    (PHP)redis String(字符串)操作
    (PHP)redis List(列表)操作
    PHP连接 redis
    PHP json 对象 数组互相转换
    循环节长度 蓝桥杯
    三羊献瑞 蓝桥杯
    立方变自身
  • 原文地址:https://www.cnblogs.com/mengyan/p/2664379.html
Copyright © 2011-2022 走看看