非阻塞队列有: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 "网站已得到响应";
}
}
收工........