您的位置:首页 > 编程语言 > Java开发

jdk中队列的实现--阻塞队列和无阻塞队列

2017-08-28 12:10 295 查看
队列有先进先出FIFO和后进先出LIFO两种模式

队列一般都采用链表实现

无阻塞队列:

class QueueElement<T>{//队列节点
QueueElement<T> next=null;
QueueElement<T> prev=null;
T obj=null;
QueueElement(T var1){
this.obj=var1;
}
}
public class Queue<T>{//这是一个双向链表,是一个FIFO模型的队列
int length=0;
QueueElement<T> head=null;//头部
QueueElement<T> tail=null;//尾部
public Queue(){}
public synchronized void enqueue(T var1){//入队
QueueElement var2=new QueueElement(var1);
if(this.head==null){//队列为空
this.head=var2;
this.tail=var2;
this.length=1;
} else {
var2.next=this.head;
this.head.prev=var2;
this.head=var2;
this.length++;
}
this.notify();//唤醒其它线程
}
public T dequeue() throws InterruptedException(){//出队
return this.dequeue(0L);
}
public synchronized T dequeue(long var1){
while(this.tail==null){//队列为空时,等待
this.wait(var1);
}

QueueElement var3=this.tail;
this.tail=var3.prev;
if(this.tail==null){//队列只有一个元素
this.head=null;
} else {
this.tail.next=null;//释放这个节点
}
--this.length;
return var3.obj;
}
public synchronized boolean isEmpty(){
return this.tail==null;
}

public final synchronized Enumeration<T> elements(){
return new FIFOQueueElemerator(this);//获取一个枚举器
}
public final synchronized Enumeration<T> reverseElements(){
return new LIFOQueueElemerator(this);//获取一个后进先出的枚举器
}
}

final class FIFOQueueEnumerator<T> implements Enumeration<T>{
Queue<T> queue;
QueueElement<T> cursor;

FIFOQueueEnumerator(Queue queue){
this.queue=queue;
this.cursor=queue.tail;
}
public boolean hasMoreElements(){
return this.cursor!=null;
}

public T nextElement(){
Queue queue=this.queue;
synchronized(this.queue){
if(this.cursor!=null){
QueueElement qe=this.cursor;
this.cursor=this.cursor.prev;
return qe.obj;
}
}
}
}
final class LIFOQueueEnumerator<T> implements Enumeration<T> {
Queue<T> queue;
QueueElement<T> cursor;

LIFOQueueEnumerator(Queue<T> var1) {
this.queue = var1;
this.cursor = var1.head;
}

public boolean hasMoreElements() {
return this.cursor != null;
}

public T nextElement() {
Queue var1 = this.queue;
synchronized(this.queue) {
if(this.cursor != null) {
QueueElement var2 = this.cursor;
this.cursor = this.cursor.next;
return var2.obj;
}
}

throw new NoSuchElementException("LIFOQueueEnumerator");
}
}


阻塞队列:



static class Node<E> {
E item;
Node<E> next;

Node(E x) { item = x; }
}

public void put(E e) throws InterruptException{//入队
if(e ==null){
throw new NullPointerException();
}
int c=-1;
Node<E> node =new Node(e);
final ReentrantLock putLock=this.putLock;//private final ReentrantLock putLock = new ReentrantLock();默认是非公平锁
final AtomicInteger count=this.count;//线程安全的一个类,用于计数
putLock.lockInterruptibly();//获取锁,如果获取失败,则线程中断,等待机会被唤醒。
try{
while(count.get()==capacity){//private final int capacity;是一个成员变量,表示队列容量,默认为Integer.MAX_VALUE;
notFull.await();//当队列满了时,线程等。。待
}
enqueuw(node);//入队
c=count.getAndIncrement();//队列中元素数量自增1;
if(c+1<capacity){
notFull.signal();//还有可用容量
}
}finally{
putLock.unlock();//释放锁
}
if(c==0)
signalNotEmpty();
}

对于ReentrantLock,在并发编程中另外一文中详解。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  链表