利用阻塞队列BlockingQueue实现线程安全的生产者消费者模型

面试过程中,一般都会问到消息中间件的相关知识,生产者消费者模型是消息中间件的基础,面试过程中可能会遇到手写一个简单的生产者消费者模型的情况,在此代码实现。

生产者代码

 

/**
 * @author Administrator
 * @date 2019/3/2
 */
public class ProducerThread implements Runnable {
    private BlockingQueue<String>blockingQueue;
    private AtomicInteger count=new AtomicInteger();
    private volatile boolean flag=true;
    public ProducerThread(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"生产者开始生产消息...");
        while (flag){
            String data=count.incrementAndGet()+" ";
            try {
                final boolean offer = blockingQueue.offer(data, 2, TimeUnit.SECONDS);
                if(offer){
                    System.out.println(Thread.currentThread().getName()+"生产者向生产队列中添加消息:"+data+"成功!");
                }else{
                    System.out.println(Thread.currentThread().getName()+"生产者向生产队列中添加消息:"+data+"失败!");
                }
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName()+"生产者停止生产消息...");
    }
    public void stop(){
        this.flag=false;
    }
}

消费者代码

/**
 * @author Administrator
 * @date 2019/3/2
 */
public class ConsumerThread implements Runnable {
    private volatile boolean flag=true;
    private BlockingQueue<String> blockingQueue;
    public ConsumerThread(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"消费者开始消费消息...");
        while(flag){
            try {
                String data=blockingQueue.poll(2, TimeUnit.SECONDS);
                if(data==null||data==""){
                    flag=false;
                    System.out.println("消费者超过两秒时间未获得消息");
                    return;
                }
                System.out.println(Thread.currentThread().getName()+"消费者消费消息"+data+"成功!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }
}

验证:

public class Main {
    public static void main(String[] args){
        BlockingQueue<String> blockingQueue=new LinkedBlockingDeque<>();
        ProducerThread producerThread=new ProducerThread(blockingQueue);
        ConsumerThread consumerThread=new ConsumerThread(blockingQueue);
        Thread t1=new Thread(producerThread);
        Thread t2=new Thread(consumerThread);
        t1.start();
        t2.start();
        try {
            Thread.sleep(10000);
            producerThread.stop();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

结果:

Thread-0生产者开始生产消息...
Thread-1消费者开始消费消息...
Thread-0生产者向生产队列中添加消息:1 成功!
Thread-1消费者消费消息1 成功!
Thread-1消费者消费消息2 成功!
Thread-0生产者向生产队列中添加消息: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生产者停止生产消息...
消费者超过两秒时间未获得消息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值