阻塞队列入门

来源:互联网 发布:dnf网络出现异常09 编辑:程序博客网 时间:2024/06/05 09:37

一.阻塞队列概述

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

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

  • 在讲述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准备取数据!....