基于LinkedBlockingQueue源码自我实现线程安全队列

LinkedBlockingQueue是一个阻塞的、线程安全的、由链表实现的双向队列,和ArrayBlockingQueue一样,是最普通也是最常用的阻塞队列。现基于LinkedBlockingQueue源码自我实现一个单向的、简化版的LinkedBlockingQueue.

package com.lzq.newInterview;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class MyLinkedBlockingQueue<E> {

    private Node<E> head;// 队头
    private Node<E> tail;// 队尾

    private static final int DEFALT_SIZE = 20;
    private int size;// 队列最大长度

    private int count;// 队列当前容量

    private ReentrantLock lock = new ReentrantLock();
    private Condition empty = lock.newCondition();
    private Condition full = lock.newCondition();

    public MyLinkedBlockingQueue() {
        head = null;
        tail = null;
        size = DEFALT_SIZE;
    }

    public MyLinkedBlockingQueue(int size) {
        head = null;
        tail = null;
        this.size = size;
    }

    // 队列尾部插入元素
    public void offer(E e) {
        if (e == null)
            return;
        try {
            lock.lock();
            while (count == size) {
                full.await();
            }
            if (head == null && tail == null) {
                Node<E> node = new Node<E>(e, null);
                head = node;
                tail = node;
            } else {
                Node<E> node = new Node<E>(e, null);
                tail.next = node;
                tail = node;
            }
            count++;
            System.out.println("offer: count=" + this.count);
            empty.signal();
        } catch (Exception exp) {
            exp.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public E poll() {
        try {
            lock.lock();
            while (count == 0) {
                empty.await();
            }
            E oldValue = head.value;
            head = head.next;
            if (head == null)
                tail = null;
            count--;
            System.out.println("poll: count=" + this.count);
            full.signal();
            return oldValue;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return null;
    }

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

        Node(E value, Node<E> next) {
            this.value = value;
            this.next = next;
        }
    }

    public static void main(String[] args) {
        final MyLinkedBlockingQueue<Integer> queue = new MyLinkedBlockingQueue<Integer>();
        for (int i = 0; i < 100; i++) {
            final int num = i;
            Thread t = new Thread(new Runnable() {
                public void run() {
                    queue.offer(num);
                }
            });
            t.start();
        }
        for (int i = 0; i < 100; i++) {
            Thread t = new Thread(new Runnable() {
                public void run() {
                    queue.poll();
                }
            });
            t.start();
        }
    }
}

部分运行结果:

offer: count=1
offer: count=2
offer: count=3
offer: count=4
offer: count=5
offer: count=6
offer: count=7
offer: count=8
offer: count=9
offer: count=10
offer: count=11
offer: count=12
poll: count=11
poll: count=10
poll: count=9
poll: count=8
poll: count=7
poll: count=6
poll: count=5
poll: count=4
poll: count=3
poll: count=2
poll: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
offer: count=2
offer: count=3
poll: count=2
poll: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
offer: count=2
poll: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
offer: count=2
poll: count=1
poll: count=0
offer: count=1
offer: count=2
poll: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
offer: count=2
poll: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
poll: count=0
offer: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
offer: count=2
poll: count=1
poll: count=0

基于LinkedBlockingQueue源码自我实现线程安全队列

上一篇:扩展 spring 的 AbstractRoutingDataSource 实现读写数据库分离


下一篇:Navicat for mysql linux 破解方法