ArrayBlockingQueue以及synchronousQueue实战

112 阅读1分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

ArrayBlockingQueue介绍

ArrayBlockingQueue是一个阻塞式的队列,继承自AbstractBlockingQueue,间接的实现了Queue接口和Collection接口。底层以数组的形式保存数据(实际上可看作一个循环数组)。常用的操作包括 add,offer,put,remove,poll,take,peek。

根据 ArrayBlockingQueue 的名字我们都可以看出,它是一个队列,并且是一个基于数组的阻塞队列。

ArrayBlockingQueue 是一个有界队列,有界也就意味着,它不能够存储无限多数量的对象。所以在创建 ArrayBlockingQueue 时,必须要给它指定一个队列的大小。

阻塞

不够加入或者取不到值就一直阻塞线程

package com.wsx.blockingQueue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

        public class BlockingQueueDemo3 {
            public static void main(String[] args) {
                BlockingQueue<Object> queue = new ArrayBlockingQueue<>(3);
                try {
                    queue.put(1);
                    queue.put(2);
                    queue.put(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                try {
                    System.out.println(queue.take());
                    System.out.println(queue.take());
                    System.out.println(queue.take());
                    //System.out.println(queue.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

超时

队列超了等几秒,如果还超就返回false

队列取不到值了就等几秒,如果还取不到值就返回null

package com.wsx.blockingQueue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

        public class BlockingQueueDemo3 {
            public static void main(String[] args) {
                BlockingQueue<Object> queue = new ArrayBlockingQueue<>(3);
                try {
                    System.out.println(queue.offer(1, 1, TimeUnit.SECONDS));
                    System.out.println(queue.offer(1, 1, TimeUnit.SECONDS));
                    System.out.println(queue.offer(1, 1, TimeUnit.SECONDS));
                    System.out.println(queue.offer(1, 1, TimeUnit.SECONDS));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                try {
                    System.out.println(queue.poll(2,TimeUnit.SECONDS));
                    System.out.println(queue.poll(2,TimeUnit.SECONDS));
                    System.out.println(queue.poll(2,TimeUnit.SECONDS));
                    System.out.println(queue.poll(2,TimeUnit.SECONDS));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

synchronousQueue的理论 SynchronousQueue没有容量。

与其他BlockingQueue不同,SynchrqnousQueue是一个不存储元素的BlockingQueue。

每一个put操作必须要等待一个take操作,否则不能继续添加元素,反之亦然。

package com.wsx.blockingQueue;

import java.sql.Time;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

        public class SynchronousQueueDemo {
            public static void main(String[] args) {
                BlockingQueue<Object> queue = new SynchronousQueue<>();

                new Thread(()->{
                    try {
                        System.out.println(Thread.currentThread().getName()+"put1");
                        queue.put(1);
                        System.out.println(Thread.currentThread().getName()+"put2");
                        queue.put(2);
                        System.out.println(Thread.currentThread().getName()+"put3");
                        queue.put(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                },"AAA").start();

                new Thread(()->{
                    try {
                        TimeUnit.SECONDS.sleep(3);
                        System.out.println(Thread.currentThread().getName()+"get1");
                        System.out.println(queue.take());

                        TimeUnit.SECONDS.sleep(3);
                        System.out.println(Thread.currentThread().getName()+"get2");
                        System.out.println(queue.take());

                        TimeUnit.SECONDS.sleep(3);
                        System.out.println(Thread.currentThread().getName()+"get3");
                        System.out.println(queue.take());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                },"BBB").start();
            }
        }

同步队列不存储元素,第一个put完必须等take过后才打印,put2,而不是直接打印

只能有一个在队列里面