ArrayBlockingQueue(阻塞隊列的一種) 的本質是一個有界數組,隊列中元素遵循先進先出的規則。 這種隊列是一種典型的有界緩衝區,一旦建立,他的長度就不能再改變。數組
final Object[] items;// 隊列容器 int count;// 隊列中的元素真實個數 final ReentrantLock lock;// 主鎖,控制全部的訪問 int takeIndex; /** 下一個要取出的元素索引*/ int putIndex;/** 下一個要存放的索引*/ private final Condition notEmpty; /** 標記隊列是不是空*/ private final Condition notFull; /** 至關於一個標誌位, 標記隊列是否存滿*/
添加元素的方法this
// 添加元素 public void put(E e) throws InterruptedException { checkNotNull(e); final ReentrantLock lock = this.lock; lock.lockInterruptibly();// 調用後會一直等待獲取鎖,可是會響應中斷,//這個方法優先考慮響應中斷,而不是響應鎖的普通獲取或重入獲取。 try { while (count == items.length)// 當隊列存滿時 notFull.await();// 阻塞等待 enqueue(e);// 存入隊列 並 喚醒 notEmpty 鎖 } finally { lock.unlock(); } } // 非空校驗 private static void checkNotNull(Object v) { if (v == null) throw new NullPointerException(); } // 入隊 private void enqueue(E x) { final Object[] items = this.items; items[putIndex] = x; if (++putIndex == items.length)// 若是隊列滿了 putIndex = 0;// 從頭開始放 count++; notEmpty.signal();//喚醒 }
取出元素的方法code
// 取出元素 public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == 0) notEmpty.await();// 隊列中元素個數爲0,等待 return dequeue();// 返回隊列中的元素 } finally { lock.unlock(); } } // 出隊 private E dequeue() { final Object[] items = this.items;// 指向容器 E x = (E) items[takeIndex];// 待返回的元素 items[takeIndex] = null;// 彈出隊列 if (++takeIndex == items.length)// 若是隊列元素取出來完了 takeIndex = 0;// 從頭開始取元素 count--;// 隊列元素個數 減一 if (itrs != null)// 這個能夠忽略 itrs.elementDequeued(); notFull.signal();// 釋放鎖。說明隊列沒有滿, 能夠入隊, return x; }
本文只是簡單介紹了 ArrayBlockingQueue 中最簡單 且 最經常使用的方法,它自己其實還有不少實用的方法,好比預防超時之類的,之後會繼續分享。索引