Java面试题(十六) 武学巅峰之阻塞队列版生产者消费者模式

一. 阻塞队列版生产者消费者模式

1. 使用到的技术包括:

	Volatile:保证可见性
	CAS/AtomicInteger:保证原子性
	BlockingQueue:保证并发性

2. 集合了前面几篇文章的精华:

1. 了 解 Volatile
2. 了 解 CAS
3. 了 解 AtomicReference
4. 了 解 阻塞队列
5. 了 解 传统生产者消费者模式

3. 阻塞队列版生产者消费者模式:

代码演示

//资源类
class MySource {
    //标识   volatile保证线程之间的可见性,保证多线程并发进行
    private volatile boolean FLAG = true; //默认开启,开始进行生产+消费
    //在多线程下使用 i++,是在给自己埋雷,使用原子整形
    private AtomicInteger atomicInteger = new AtomicInteger(); //默认值为 0
    //传接口,不传具体实现类,为了更好的适配,更通用
    BlockingQueue<String> blockingQueue = null;
    //有参构造
    public MySource(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;
        //可以获得具体传入的是什么阻塞队列类
        System.out.println(blockingQueue.getClass().getName());
    }

    //生产者
    public void prod() throws Exception {

        String data = null;
        boolean res;

        //判断
        while (FLAG) {
            data = atomicInteger.incrementAndGet() + "";
            //添加数据
            res = blockingQueue.offer(data, 2L, TimeUnit.SECONDS);
            if (res) {
                System.out.println(Thread.currentThread().getName() + "\t 插入数据 " + data + " 成功");
            } else {
                System.out.println(Thread.currentThread().getName() + "\t 插入数据 " + data + " 失败");
            }
            //一秒生产一个
            TimeUnit.SECONDS.sleep(1);
        }
        System.out.println(Thread.currentThread().getName() + "生产结束 FLAG: false ");
    }

    //消费者
    public void consumer() throws Exception {

        String result = null;

        //判断
        while (FLAG) {
            //取数据
            result = blockingQueue.poll(2L, TimeUnit.SECONDS);
            if (null == result || result.equalsIgnoreCase("")) {
                //如果队列里面没有数据了,可以把标识设置为false
                FLAG = false;
                System.out.println(Thread.currentThread().getName() + "\t 队列里面没有数据可以消费了,退出。。。");
                return;
            }
            System.out.println(Thread.currentThread().getName() + "\t 移出数据 " + result + " 成功");
        }
        System.out.println(Thread.currentThread().getName() + "消费结束 FLAG: false ");
    }

    //停止生产消费模式
    public void stop() throws Exception {
        this.FLAG = false;
    }
}

调用

public static void main(String[] args) throws Exception {
        //操作资源类
        MySource mySource = new MySource(new ArrayBlockingQueue<>(5));

        //生产线程
        new Thread(() -> {
            try {
                System.out.println(Thread.currentThread().getName() + "生产线程启动。。。");
                mySource.prod();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "Producer").start();

        //消费线程
        new Thread(() -> {
            try {
                System.out.println(Thread.currentThread().getName() + "消费线程启动。。。");
                mySource.consumer();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "Consumer").start();

        //5秒后停止生产消费模式
        try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }

        System.out.println();
        System.out.println();
        System.out.println();
        System.out.println("5秒时间到,停止。");
        mySource.stop();
    }

运行结果
在这里插入图片描述

总结:阻塞队列版生产者消费者模式适用于多线程并发下使用。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值