zoukankan      html  css  js  c++  java
  • 阿里笔试-生产者消费者模式

    /**
    使用“生产者-消费者模式”编写代码实现:线程A随机间隔(10~200ms)按顺序生成1到100的数字(共100个),
    放到某个队列中.3个线程B、C、D即时消费这些数据,线程B打印(向控制台)所有被2整除的数,
    线程C打印被3整除的数,线程D打印其它数据,要求数字的打印是有序的(从1到100)
    限时40分钟,可以使用IDE及第三方类库
    **/

     先说一下阿里大牛的评价:我下面写的程序有个问题,如果B线程挂起了,C,D线程运行的话,有可能顺序会不一致。当然不能用三个queue,让B,C,D分别消费,因为太简单了。

    应该这样,每次取出一个数来,使用wait(),notify(),先让B运行,然后C运行,然后D运行;就能保证顺序了,下面是我写的程序,暂时没有时间修改,以后有时间了,会进行修改:

    package com.sankuai.qcs.regulation.TestCase;
    
    import lombok.Data;
    
    @Data
    public class aliObj implements Comparable<aliObj> {
        private final int intData;
    
        public boolean BisDone;
        public boolean CisDone;
        public aliObj(int d){
            intData = d;
            BisDone=false;
            CisDone=false;
        }
    
        public int getData(){
            return intData;
        }
        @Override
        public String toString(){
            return "data:"+intData;
        }
    
    
        @Override
        public int compareTo(aliObj o) {
    
            if(this.intData>o.intData) {
                return 1;
            }
                else if(this.intData<o.intData) {
                return -1;
            }
            else {
                return 0;
            }
    
        }
    }
    package com.sankuai.qcs.regulation.TestCase;
    
    import java.util.Comparator;
    import java.util.Random;
    import java.util.concurrent.PriorityBlockingQueue;
    import java.util.concurrent.TimeUnit;
    
    public class Producer implements Runnable {
    
        private volatile boolean isRunning = true;
        int capacity = 100;
        PriorityBlockingQueue<aliObj> queue = new PriorityBlockingQueue(capacity, new Comparator<aliObj>() {
            @Override
            public int compare(aliObj i1, aliObj i2) {
                return i2.getIntData() - i1.getIntData();
            }
        });
    
        public Producer(PriorityBlockingQueue<aliObj> queue){
            this.queue = queue;
        }
    
        @Override
        public void run() {
            if (isRunning) {
    
                Random r = new Random();
                System.out.println("start producting id:" + Thread.currentThread().getId());
                try {
    
                    for (int i = 0; i < 100; i++) {
                        Thread.sleep(10 + r.nextInt(190)); //停顿 10~200毫秒
    
                        System.out.println(i+1 + " 加入队列");
                        if (!queue.offer(new aliObj(i + 1), 2, TimeUnit.SECONDS)) {
                            System.err.println(i+1+" 加入队列失败");
                        }
                    }
    
    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                }
    
            }
        }
    
        public void stop() {
            isRunning = false;
        }
    
    
    }
    package com.sankuai.qcs.regulation.TestCase;
    
    import java.util.concurrent.PriorityBlockingQueue;
    
    public class ConsumerB implements Runnable{
        private PriorityBlockingQueue<aliObj> queue;
        public ConsumerB(PriorityBlockingQueue<aliObj> queue){
            this.queue = queue;
        }
    
        @Override
        public void run() {
            System.out.println("start ConsumerB id :"+Thread.currentThread().getId());
    
            try{
                while(true){
                    aliObj data = queue.take();
                    if(data != null)
                    {
                        if(data.isBisDone()==false && data.getData()%2==0) {
    
                            System.out.println("可以被2整除的数:"+data);
                            data.setBisDone(true);
                          if(data.getData()%3==0)  queue.offer(data);
    
                        }
    
                        else{
                            queue.offer(data);
                        }
                    }
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            }
        }
    
    }
    package com.sankuai.qcs.regulation.TestCase;
    
    import java.util.concurrent.PriorityBlockingQueue;
    
    public class ConsumerC implements Runnable{
        private PriorityBlockingQueue<aliObj> queue;
        public ConsumerC(PriorityBlockingQueue<aliObj> queue){
            this.queue = queue;
        }
    
        @Override
        public void run() {
            System.out.println("start ConsumerC id :"+Thread.currentThread().getId());
    
            try{
                while(true){
                    aliObj data = queue.take();
                    if(data != null) {
                        if (data.isCisDone()==false &&  data.getData() % 3 == 0) {
    
                            System.out.println("可以被3整除的数:" + data);
    
                         if(data.getData()%2==0) {
                             data.setCisDone(true);
                             queue.offer(data);
                         }
    
                        } else {
                            queue.offer(data);
                        }
                    }
                    }
    
            }catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            }
        }
    
    }
    package com.sankuai.qcs.regulation.TestCase;
    
    import java.util.concurrent.PriorityBlockingQueue;
    
    public class ConsumerD implements Runnable{
        private PriorityBlockingQueue<aliObj> queue;
        public ConsumerD(PriorityBlockingQueue<aliObj> queue){
            this.queue = queue;
        }
    
        @Override
        public void run() {
            System.out.println("start ConsumerD id :"+Thread.currentThread().getId());
    
            try{
                while(true){
                    aliObj data = queue.take();
                    if(data != null)
                    {
                        if((data.getData()%2!=0)&&(data.getData()%3!=0)) {
    
                            System.out.println("既不可以被2整除,也不可以被3整除的数:"+data);
                            
                        }
                    }
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            }
        }
    
    }
    package com.sankuai.qcs.regulation.TestCase;
    import java.util.concurrent.*;
    
    public class Main {
        public static void main(String[] args) throws InterruptedException {
            PriorityBlockingQueue<aliObj> queue = new PriorityBlockingQueue<>();
            Producer p1 = new Producer(queue);
            ConsumerB b1 = new ConsumerB(queue);
    
            ConsumerC c1 = new ConsumerC(queue);
            ConsumerD d1 = new ConsumerD(queue);
            ExecutorService service = Executors.newCachedThreadPool();
            service.execute(p1);
    
            service.execute(b1);
            service.execute(c1);
            service.execute(d1);
            p1.stop();
            Thread.sleep(3000);
            service.shutdown();
        }
    }
  • 相关阅读:
    一次线上问题引发的对于C#中相等判断的思考
    Node中的模块引入机制
    Node 各个版本支持ES2015特性的网站
    使用Chrome 中的 ssh 插件登陆 linux 服务器
    vmWare 虚机文件不能启动的事故处理
    JaveScript 中使用 XSLT转换XML文档
    浏览器上的坐标体系相关概念(客户区,页面,屏幕)
    visual Studio 中使用正则表达式来进行查找替换
    JavaScript 执行环境及作用域
    Laravel save部分字段失效的bug问题解决
  • 原文地址:https://www.cnblogs.com/aspirant/p/11694951.html
Copyright © 2011-2022 走看看