阿里笔试-生产者消费者模式

/**
使用“生产者-消费者模式”编写代码实现:线程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();
    }
}

 

posted @ 2019-10-17 20:44  aspirant  阅读(1818)  评论(3编辑  收藏  举报