欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

阻塞队列入门

程序员文章站 2022-05-02 13:09:54
...

一.阻塞队列概述

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

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

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

上一篇: 多进程入门

下一篇: 队列阻塞浅析