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

队列有先进先出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,在并发编程中另外一文中详解。

put流程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值