手写生产-消费者的实现(通过阻塞队列实现)

思路分析:

1、两个线程、一个生产、一个消费,要保证可见性,所以需要volatile
2、多线程下要保证原子性,所以生产消费的数据用IAtomicnteger
3、使用那种阻塞队列需要依赖传入的参数来决定,所以构造传接口进来
4、使用阻塞队列中包含超时的offer、poll

代码实现:

/**
 * @title: MyResource
 * @description: 实现生产-消费者
 * @author:quLiangquan
 * @date 2019/8/16 16:22
 **/

//资源类
public class MyResource {
    private volatile boolean FLAG = true;
    private AtomicInteger atomicInteger = new AtomicInteger();
    private BlockingQueue<String> blockingQueue = null;

    //构造方法
    public MyResource(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    public void myProd() 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() + " 写入 " + data + " 成功");
            } else {
                System.out.println(Thread.currentThread().getName() + " 写入 " + data + " 失败");
            }
            TimeUnit.SECONDS.sleep(1);
        }
        System.out.println(Thread.currentThread().getName() + " 叫停了、不生产了");
    }

    public void myConsumer() throws Exception {
        String res = null;
        while (FLAG) {

            res = blockingQueue.poll(2, TimeUnit.SECONDS);
            if (null == res || res.equalsIgnoreCase("")) {
                FLAG = false;
                System.out.println(Thread.currentThread().getName() + " 超过2秒没取到数据、退出消费");

                return; //停止
            }
            System.out.println(Thread.currentThread().getName() + " 消费 " + res + " 成功");
        }
    }

    public void stop() {
        this.FLAG = false;
    }

    public static void main(String[] args) throws Exception{

        //资源类
        MyResource myResource = new MyResource(new ArrayBlockingQueue<>(10));

        //线程操作资源类
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " 生产线程启动");
            try {
                myResource.myProd();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"Prod" ).start();

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

        TimeUnit.SECONDS.sleep(5);

        System.out.println("叫停");
        myResource.stop();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值