生产者消费者问题 阻塞队列版

生产者消费者问题 阻塞队列版

package com.zyk;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

class MySource{
      //加volatile保证可见性  加volatile保证及时通知 如生产被叫停时 要通知消费者线程标志位被改为false
      //标志位为true时 生产+消费同时进行 标志位为false时 生产+消费都要被结束
      private volatile boolean flag=true;
      //原子整型类
      private AtomicInteger atomicInteger=new AtomicInteger();
      //BlockingQueue作为MySource的一个属性
      BlockingQueue blockingQueue=null;
      //构造方法传一个具体的BlockingQueue的实现类对象
      public MySource(BlockingQueue blockingQueue){
          this.blockingQueue=blockingQueue;
          //这里打印一下 看是具体哪种BlockingQueue
          System.out.println(blockingQueue.getClass().getName());
      }
      public  void myProduce()throws Exception{
          //生产的数据用data存起来
          String data=null;
          //offer方法返回一个boolean值 标志生产成功与否
          boolean resultValue;
          while (flag){
               data=atomicInteger.incrementAndGet()+"";
              //offer进去 返回true    offer失败 返回false
               resultValue=blockingQueue.offer(data,2, TimeUnit.SECONDS);
              if (resultValue) {
                  System.out.println(Thread.currentThread().getName()+"\t 生产成功"+data);
              } else {
                  System.out.println(Thread.currentThread().getName()+"\t 生产失败"+data);
              }
              //一秒生产1次
              //这句话保证了生产一个 消费一个 生产一个 消费一个的结果
              //如果将这句话注释掉 可能出现的结果是生产者线程一直抢到cpu执行权 一直执行生产 生产好几个才轮到消费者线程
              //加上这句话 当生产一个时 就暂停一下 交给消费者线程去消费
              TimeUnit.SECONDS.sleep(1);
          }
          //结束while循环 标志位是false 生产+消费都被停止
          System.out.println(Thread.currentThread().getName()+"被叫停");
      }

      public void myConsumer()throws Exception{
          String result=null;
          while(flag){
             result= (String) blockingQueue.poll(2,TimeUnit.SECONDS);
             //如果消费者取不到东西
             if(null==result||result.equalsIgnoreCase("")){
                 //修改标志位
                 flag=false;
                 System.out.println(Thread.currentThread().getName()+"超过2秒没有取到 消费退出");
                 return;
             }
                 System.out.println(Thread.currentThread().getName()+"消费成功"+result);
          }
      }
      //所有线程都被叫停
      public void stop(){
          this.flag=false;
      }
}
public class Product_ConsumerDemo3 {
    public static void main(String[] args)  {
        MySource mySource=new MySource(new ArrayBlockingQueue(3));
        new Thread(()->{
            System.out.println("生产线程启动");
            try {
                mySource.myProduce();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"生产线程").start();


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

        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println();
        System.out.println();
        System.out.println("5秒之后 退出所有活动");
        mySource.stop();
    }
}

在这里插入图片描述

发布了39 篇原创文章 · 获赞 19 · 访问量 1475

猜你喜欢

转载自blog.csdn.net/weixin_44222272/article/details/105335067