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();
        }
    }
  • 相关阅读:
    利用DTrace实时检测MySQl
    改进MySQL Order By Rand()的低效率
    RDS for MySQL查询缓存 (Query Cache) 的设置和使用
    RDS For MySQL 字符集相关说明
    RDS for MySQL 通过 mysqlbinlog 查看 binlog 乱码
    RDS for MySQL Mysqldump 常见问题和处理
    RDS for MySQL Online DDL 使用
    RDS MySQL 表上 Metadata lock 的产生和处理
    RDS for MySQL 如何使用 Percona Toolkit
    北京已成为投融资诈骗重灾区:存好骗子公司黑名单,谨防上当!
  • 原文地址:https://www.cnblogs.com/aspirant/p/11694951.html
Copyright © 2011-2022 走看看