阻塞队列入门

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33248299/article/details/78869105

一.阻塞队列概述

  • 队列包含固定长度的队列和不固定长度的队列

  • 队列还可以分还可分为阻塞队列和不阻塞队列

  • 在讲述condition时提了下BoundedBuffer,实际过程中直接用ArrayBlockingQueue这个类就行了,提供了BoundedBuffer那片代码的功能

    • 查看ArrayBlockingQueue这个类,发现它实现了一个BlockingQueue<E> 接口

这里写图片描述

如果此时你想在队列中添加元素,有三个方法add,offer,put,使用之后的效果不同
就拿Insert来说明,当有一个队列,固定长度为8,而此时队列已满,用add添加,会报错;用offer添加,会返回一个false,添加失败,成功为true

这里写图片描述

而用put就会等待,即就是阻塞了;取元素也是如此的

二.阻塞队列例子

public class BlockingQueueTest {
            public static void main(String[] args) {
                final BlockingQueue queue = new ArrayBlockingQueue(3);//空间大小为3
                for(int i=0;i<2;i++) {
                    new Thread() {
                        public void run() {
                            while(true) {
                            try {
                                Thread.sleep((long)(Math.random()*1000));
                                System.out.println(Thread.currentThread().getName()+"准备放数据!");
                                queue.put(1);
                                System.out.println(Thread.currentThread().getName()+"已经放了数据, "+"队列目前有"+queue.size()+"个数据");
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            }
                        };
                    }.start();

                }

                new Thread() {
                    public void run() {
                        while(true) {
                        try {
                            //将此处的睡眠时间分别改为100和1000,观察运行结果
                            Thread.sleep(1000);
                            System.out.println(Thread.currentThread().getName()+"准备取数据!");
                             queue.take();
                             System.out.println(Thread.currentThread().getName()+"已经取走数据, "+
                             "队列目前有"+queue.size()+"个数据");
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        }

                    };
                }.start();
            }
}

控制台输出

Thread-1准备放数据!
Thread-1已经放了数据, 队列目前有1个数据
Thread-0准备放数据!
Thread-0已经放了数据, 队列目前有2个数据
Thread-0准备放数据!
Thread-0已经放了数据, 队列目前有3个数据
Thread-0准备放数据!
Thread-1准备放数据!
Thread-2准备取数据!
Thread-2已经取走数据, 队列目前有2个数据
Thread-0已经放了数据, 队列目前有3个数据
Thread-0准备放数据!
Thread-2准备取数据!
Thread-2已经取走数据, 队列目前有2个数据
Thread-1已经放了数据, 队列目前有3个数据
Thread-1准备放数据!
....
public class BlockingQueueTest {
            public static void main(String[] args) {
                final BlockingQueue queue = new ArrayBlockingQueue(3);//空间大小为3
                for(int i=0;i<2;i++) {
                    new Thread() {
                        public void run() {
                            while(true) {
                            try {
                                Thread.sleep((long)(Math.random()*1000));
                                System.out.println(Thread.currentThread().getName()+"准备放数据!");
                                queue.put(1);
                                System.out.println(Thread.currentThread().getName()+"已经放了数据, "+"队列目前有"+queue.size()+"个数据");
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            }
                        };
                    }.start();

                }

                new Thread() {
                    public void run() {
                        while(true) {
                        try {
                            Thread.sleep(100);//取得太快,会造成存入一个就立马取出来了
                            System.out.println(Thread.currentThread().getName()+"准备取数据!");
                             queue.take();
                             System.out.println(Thread.currentThread().getName()+"已经取走数据, "+
                             "队列目前有"+queue.size()+"个数据");
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        }

                    };
                }.start();
            }
}

控制台输出

Thread-2准备取数据!
Thread-0准备放数据!
Thread-0已经放了数据, 队列目前有1个数据
Thread-2已经取走数据, 队列目前有0个数据
Thread-2准备取数据!
Thread-1准备放数据!
Thread-1已经放了数据, 队列目前有1个数据
Thread-2已经取走数据, 队列目前有0个数据
Thread-0准备放数据!
Thread-0已经放了数据, 队列目前有1个数据
Thread-2准备取数据!
Thread-2已经取走数据, 队列目前有0个数据
Thread-2准备取数据!
Thread-0准备放数据!
Thread-0已经放了数据, 队列目前有1个数据
Thread-2已经取走数据, 队列目前有0个数据
Thread-2准备取数据!
Thread-1准备放数据!
Thread-1已经放了数据, 队列目前有1个数据
Thread-2已经取走数据, 队列目前有0个数据
Thread-2准备取数据!
Thread-0准备放数据!
Thread-0已经放了数据, 队列目前有1个数据
Thread-2已经取走数据, 队列目前有0个数据
Thread-1准备放数据!
Thread-1已经放了数据, 队列目前有1个数据
Thread-2准备取数据!
Thread-2已经取走数据, 队列目前有0个数据
Thread-1准备放数据!
Thread-1已经放了数据, 队列目前有1个数据
Thread-2准备取数据!
Thread-2已经取走数据, 队列目前有0个数据
Thread-2准备取数据!
....

猜你喜欢

转载自blog.csdn.net/qq_33248299/article/details/78869105