非阻塞队列有:ArrayDeque、PriorityQueue、ConcurrentLinkedQueue

之前都说过阻塞队列了,其实差别都不大,阻塞和非阻塞的区别在于阻塞队列有put和take方法进行阻塞,而非阻塞队列则没有这两个方法,同时poll和offer方法也不提供超时参数设定。

ArrayDeque非阻塞的数组结构队列,底层数组实现,且双向操作,即可以向头添加数据也可向尾添加数据,既可头部取数据亦可尾部取数据。

基本上可以分成两类,一类是以add,remove,get开头的方法,这类方法失败后会抛出异常,一类是以offer,poll,peek开头的方法,这类方法失败之后会返回特殊值,如null。大部分方法基本上都是可以根据命名来推断其作用,如addFirst,当然就是从队列头部插入,removeLast,便是从队列尾部移除,get和peek只获取元素而不移除,getFirst方法调用时,如果队列为空,会抛出NoSuchElementException异常,而peekFirst在队列为空时调用则返回null。

 

 

从队列首部插入/取出

 

从队列尾部插入/取出

 

失败抛出异常

失败返回特殊值

失败抛出异常

失败返回特殊值

插入

addFirst(e)    push()

offerFirst(e)

addLast(e)

offerLast(e)

移除

removeFirst()  pop()

pollFirst()

removeLast()

pollLast()

获取

getFirst()

peekFirst()

getLast()

peekLast()

 

常用阻塞队列给出的方法

方法\处理方式

抛出异常

返回特殊值

一直阻塞

超时退出

插入方法

add(e)

offer(e)

put(e)

offer(e,time,unit)

移除方法

remove()

poll()

take()

poll(time,unit)

检查方法

element()

peek()

不可用

不可用

 

PriorityQueue队列是优先级非阻塞队列,方法都是类似的不多说了。可以参考之前写的阻塞优先级队列。

 

ConcurrentLinkedQueue队列是基于链表的非阻塞队列,感觉没啥区别,只是底层是通过链表来实现的。非阻塞方法和上面的ArrayDeque类似,只是他的只能向队列尾部添加数据,所以没有Last和First方法。总的没啥不一样的地方。用法也比较简单不细记录了。

简单写下代码测试吧



package com.example.web.web;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayDeque;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;

@RestController
public class HomeController {

    @RequestMapping("/index")
    public String index() throws Exception {
        ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();

        //生产者
        new Thread(() ->
        {
            try {
                for (int i = 0; i < 5; i++) {
                    System.out.println("生产者begin");
                    queue.offer("测试数据" + i);
                    System.out.println("生产者end");
                }
            } catch (Exception ex) {
                System.out.println(ex);
            }
        }).start();

        //消费者
        new Thread(() ->
        {
            try {
                for (int i = 0; i < 6; i++) {
                    System.out.println("==消费者begin");
                    TimeUnit.SECONDS.sleep(1);
                    String aa = queue.poll();
                    System.out.println("==消费者end" + aa);
                }
            } catch (Exception ex) {
                System.out.println(ex);
            }
        }).start();

        //主线程也等待下
        TimeUnit.SECONDS.sleep(15);
        return "网站已得到响应";
    }
}



 

收工........