并发队列

Posted tinghao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并发队列相关的知识,希望对你有一定的参考价值。

简介:

   并发队列Queue,队列其实就是一个容器

    1.同步容器
      Vector容器,HashTable容器,都是线程安全
      如果同步容器使用foreach迭代过程中修改了元素的值,则会出现ConcurrentModificationException异常
      可以使用iterator迭代器解决,但是在多线程并行情况下,修改容器中数据,会发生阻塞或者报NoSech异常
    2.并发容器,队列
      无界限:代表队列当中可以存放N个数据,没有长度限制
      有界限:队列当中规定只能存放多少个数据,超过则阻塞
    3.ConcurrentLinkedQueue,无界限的队列,可以采用add()方法(底层调用offer())或者offer方法将数据存放到队列当中,通过peek和poll方法获取队列头数据
      peek()方法获取数据,但是该数据没有出列
      poll()方法获取数据,完成后该数据出列
      peek和poll当队列当中没有数据时,获取的数据为null,不会产生阻塞

技术图片
public static void main(String[] args) {
                    //准备队列
                    ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
                    //存放数据
                    queue.offer("张三");
                    queue.offer("李四");
                    queue.offer("王五");

                    //获取队列中数据个数
                    System.out.println("队列中当前有:"+queue.size()+"个数据~");
                    //获取队列中头数据  poll()方法相当于消费了队列中的数据,队列数据会随之删除
                    System.out.println("获取队列中的数据:"+queue.poll());
                    System.out.println("队列中当前有:"+queue.size()+"个数据~");
                    //获取队列中数据,但是不会删除
                    System.out.println("获取队列中的数据:"+queue.peek());
                    System.out.println("获取队列中的数据:"+queue.peek());
                    System.out.println("队列中当前有:"+queue.size()+"个数据~");
                }
技术图片

    4.有边界的阻塞队列BlockingQueue
      put方法和take会发生阻塞,add以及offer还有poll和peek不会发生阻塞
        4.1 ArrayBlockingQueue:当队列没有数据时,获取时为null,当队列满时,会报异常或者入队失败

技术图片
public static void main(String[] args) throws InterruptedException {
                        //ArrayBlockingQueue底层数组实现
                        ArrayBlockingQueue<String> arrays = new ArrayBlockingQueue<String>(3);
                        arrays.add("张三");
                        arrays.add("李四");
                        arrays.add("王五");
                        System.out.println(arrays.poll());

                        arrays.offer("赵六",1000, TimeUnit.MILLISECONDS);

                        System.out.println(arrays.poll());
                        System.out.println(arrays.poll());
                        System.out.println(arrays.poll());

                    }
技术图片

    5.LinkedBlockingQueue 初始可以指定队列大小,如果不指定则按照Integer.MaxValue值进行设定

技术图片
public static void main(String[] args) throws InterruptedException {
                    //ArrayBlockingQueue底层数组实现
                    LinkedBlockingQueue <String> arrays = new LinkedBlockingQueue<String>(100);

                    new Thread(()->{
                        for (int i = 0; i < 100; i++) {
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            try {
                                arrays.put("item"+i);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }).start();

                    new Thread(()->{
                        for (int i = 0; i < 100; i++) {
                            try {
                                System.out.println(arrays.take()+i);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }).start();
                }
技术图片

以上是关于并发队列的主要内容,如果未能解决你的问题,请参考以下文章

golang goroutine例子[golang并发代码片段]

如何从设置中获取数据并发送到此片段

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题

转: Java并发编程之二十一:并发新特性—阻塞队列和阻塞栈(含代码)

golang代码片段(摘抄)