BlockingQueue阻塞队列

本文深入探讨了Java并发编程中的BlockingQueue阻塞队列,阐述了其工作原理和好处,如避免忙等和提高效率。通过示例展示了ArrayBlockingQueue、SynchronousQueue等类型的使用,以及在生产者消费者模式中的应用。同时,对比了synchronized与Lock的区别,并解释了Lock的优势。此外,还讨论了线程池和中间件中 BlockingQueue 的作用。
摘要由CSDN通过智能技术生成


BlockingQueue

1. 阻塞队列



2. 为什么?阻塞队列有什么好处:


3.架构介绍

4. BlockingQueue种类分类


5. BlockingQueue核心方法

工作中用超时offer poll这一组


/**
 * 阻塞队列
 *
 * 1    两个数据结构:栈/队列
 *  1.1 栈       后进先出
 *  1.2 队列      先进先出
 *  1.3 总结
 *
 * 2    阻塞队列
 *  2.1 阻塞   必须要阻塞/不得不阻塞
 *
 * 3    how
 */
public class BlockingQueueDemo {
    public static void main(String[] args) {
        //List list = new ArrayList();
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        System.out.println(blockingQueue.add("a"));
        System.out.println(blockingQueue.add("b"));
        System.out.println(blockingQueue.add("c"));
        System.out.println(blockingQueue.add("d"));

    }
}

输出结果
当队列满了再添加会抛出java.lang.IllegalStateException: Queue full异常信息

true
true
true
Exception in thread "main" java.lang.IllegalStateException: Queue full
	at java.util.AbstractQueue.add(AbstractQueue.java:98)
	at java.util.concurrent.ArrayBlockingQueue.add(ArrayBlockingQueue.java:312)
	at wj.leslie.day3.BlockingQueueDemo.main(BlockingQueueDemo.java:28)

public class BlockingQueueDemo {
    public static void main(String[] args) {
        //List list = new ArrayList();
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        System.out.println(blockingQueue.add("a"));
        System.out.println(blockingQueue.add("b"));
        System.out.println(blockingQueue.add("c"));
//        System.out.println(blockingQueue.add("d"));

        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());

    }
}

输出结果
当队列为空 ,再取数据会抛出java.util.NoSuchElementException异常

true
true
true
a
b
c
Exception in thread "main" java.util.NoSuchElementException
	at java.util.AbstractQueue.remove(AbstractQueue.java:117)
	at wj.leslie.day3.BlockingQueueDemo.main(BlockingQueueDemo.java:33)

public class BlockingQueueDemo {
    public static void main(String[] args) {
        //List list = new ArrayList();
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        System.out.println(blockingQueue.offer("a"));
        System.out.println(blockingQueue.offer("b"));
        System.out.println(blockingQueue.offer("c"));
        System.out.println(blockingQueue.offer("d"));

        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
    }
}

输出结果

true
true
true
false
a
b
c
null

public class BlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        //List list = new ArrayList();
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        blockingQueue.put("a");
        blockingQueue.put("b");
        blockingQueue.put("c");
        blockingQueue.put("d");
    }
}
public class BlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        //List list = new ArrayList();
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        blockingQueue.put("a");
        blockingQueue.put("b");
        blockingQueue.put("c");
//        blockingQueue.put("d");
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());

    }
}


public class BlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        //List list = new ArrayList();
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        System.out.println(blockingQueue.offer("a"));
        System.out.println(blockingQueue.offer("b"));
        System.out.println(blockingQueue.offer("c"));
        System.out.println(blockingQueue.offer("d",3L,TimeUnit.SECONDS));
    }
}

输出结果

true
true
true
//3秒后输出false
false

SynchronousQueue

public class SynchronousQueueDemo {
    public static void main(String[] args) {
        BlockingQueue<String> blockingQueue = new SynchronousQueue<>();
        new Thread(()->{
            try{
                System.out.println(Thread.currentThread().getName()+"\t put 1");
                blockingQueue.put("1");

                System.out.println(Thread.currentThread().getName()+"\t put 2");
                blockingQueue.put("2");

                System.out.println(Thread.currentThread().getName()+"\t put 3");
                blockingQueue.put("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"AA").start();

        new Thread(()->{
            try{
                //暂停一会线程
                try { TimeUnit.SECONDS.sleep(5); }catch (InterruptedException e){ e.printStackTrace(); }
                System.out.println(Thread.currentThread().getName()+"\t "+blockingQueue.take());

                try { TimeUnit.SECONDS.sleep(5); }catch (InterruptedException e){ e.printStackTrace(); }
                System.out.println(Thread.currentThread().getName()+"\t "+blockingQueue.take());

                try { TimeUnit.SECONDS.sleep(5); }catch (InterruptedException e){ e.printStackTrace(); }
                System.out.println(Thread.currentThread().getName()+"\t "+blockingQueue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"BB").start();
    }
}


6.BlockingQueue用在哪里

生产者消费者模式
1. 传统版
/**
 * @Author leslie
 * @Date 2021/9/11
 * 题目:一个初始值为零的遍历,两个线程对其交替操作,一个加1一个减1,来5轮
 * 1    线程     操作      资源类
 * 2    判断     干活      通知
 * 3    防止虚假唤醒机制
 */
class ShareDate{//资源类
    private int number = 0;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void increment() throws Exception{
        lock.lock();
        try{
            //1 判断
            while(number!=0){
                //等待,不能生产
                condition.await();
            }
            //2 干活
            number++;
            System.out.println(Thread.currentThread().getName()+"\t "+number);

            //3.通知唤醒
            condition.signalAll();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public void decrement() throws Exception{
        lock.lock();
        try{
            //1 判断
            while(number==0){
                //等待,不能生产
                condition.await();
            }
            //2 干活
            number--;
            System.out.println(Thread.currentThread().getName()+"\t "+number);

            //3.通知唤醒
            condition.signalAll();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

}

public class ProdConsunmer_TraditionDemo {
    public static void main(String[] args) {
        ShareDate shareDate = new ShareDate();
        new Thread(()->{
            for (int i = 1; i <=5 ; i++) {
                try {
                    shareDate.increment();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        },"AA").start();
        new Thread(()->{
            for (int i = 1; i <=5 ; i++) {
                try {
                    shareDate.decrement();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        },"BB").start();
    }
}


传统版文章链接


2. 阻塞队列版
/**
 * @Author leslie
 * @Date 2021/9/11
 * volatile/CAS/AtomicInteger/BlockingQueue/线程交互/原子引用
 */
class MyResource{
    private volatile boolean FALG = true;//默认开始,进行生产+消费
    private AtomicInteger atomicInteger = new AtomicInteger();
    BlockingQueue<String> blockingQueue = null;
    public MyResource(BlockingQueue<String> blockingQueue){
        this.blockingQueue = blockingQueue;
        System.out.println(blockingQueue.getClass().getName());
    }

    public void myProd() throws Exception{
        String data = null;
        boolean retValue;
        while (FALG){
            data = atomicInteger.incrementAndGet()+"";
            retValue = blockingQueue.offer(data,2L, TimeUnit.SECONDS);
            if(retValue){
                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()+"\t 大老板叫停了,表示FLAG=false,生产动作结束");
    }

    public void myConsumer() throws Exception{
        String result = null;
        while (FALG){
            result = blockingQueue.poll(2L,TimeUnit.SECONDS);
            if(null == result || result.equalsIgnoreCase("")){
                FALG = false;
                System.out.println(Thread.currentThread().getName()+"\t 超过两秒钟没有取到蛋糕,消费退出");
                return;
            }
            System.out.println(Thread.currentThread().getName()+"\t 消费队列蛋糕"+result+"成功");
        }
    }
    public void stop() throws Exception{
        this.FALG = false;
    }

}
public class ProdConsunmer_BlockQueueDemo {
    public static void main(String[] args) throws Exception {
        MyResource myResource = new MyResource(new ArrayBlockingQueue<>(10));
        new Thread(()->{
            System.out.println(Thread.currentThread().getName()+"\t 生产线程启动");
            try {
                myResource.myProd();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"Prod").start();
        new Thread(()->{
            System.out.println(Thread.currentThread().getName()+"\t 消费线程启动");
            System.out.println();
            System.out.println();
            try {
                myResource.myConsumer();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"Consumer").start();

        //暂停一会线程
        try{ TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }

        System.out.println();
        System.out.println();
        System.out.println();

        System.out.println("5秒钟时间到,大老板main线程叫停,活动结束");
        myResource.stop();
    }
}


线程池
中间件

7. synchronized和Lock有什么区别? 用新的Lock有什么好处? 你举例说说

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值