比較:數組
1)隊列的大小不一樣: ArrayBlockingQueue 是有界隊列,且初始化時必須指定隊列的大小。 LinkedBlockingQueue 是無界隊列,在初始化的時候能夠指定隊列的大小從而變成有界隊列。注:對於無界隊列,當入列速度大於出列速度時可能會形成內存溢出。 2)實現的方式不一樣: ArrayBlockingQueue 使用一個Object數組來存儲元素。 LinkedBlockingQueue 使用鏈表來存儲元素。 3)實現同步的方式不一樣: ArrayBlockingQueue 使用一個ReentrantLock來保證線程安全:入列和出列前都須要獲取該鎖。 LinkedBlockingQueue 使用兩個ReentrantLock來保證線程安全:入列前須要獲取到入列鎖(putLock),出列前須要獲取到出列鎖(takeLock),實現了入列鎖和出列鎖的分離,故LinkedBlockingQueue的併發性比較好。
方法: ArrayBlockingQueue安全
1)入列方法: 1> put(E e)方法:獲取到鎖後,將元素插入到隊列的尾部而且使用signal()隨機喚醒一個在出列方法中(take方法、poll的超時方法)中阻塞的線程;若是隊列已滿,則調用Condition的await()阻塞當前線程。 2> offer(E e)方法:獲取到鎖後,將元素插入到隊列的尾部而且使用signal()隨機喚醒一個在出列方法中(take方法、poll的超時方法)阻塞的線程,插入成功返回true;若是隊列已滿,直接返回false。 3> offer(E e, long timeout, TimeUnit unit)方法:同put()方法同樣,惟一不一樣的是:put方法是永久等待,而這個方法是超時等待。 4> add(E e)方法:內部調用offer()方法,若是offer方法插入成功,則返回true,不然拋出異常(隊列已滿)。 2)出列方法: 1> take()方法:獲取到鎖後,將隊列的頭元素返回(同時將隊列的頭元素移出隊列)而且使用signal()隨機喚醒一個在入列方法(put方法、offer的超時方法)中阻塞的線程;若是隊列爲空,則調用await()阻塞當前線程。 2> poll()方法:獲取到鎖後,將隊列的頭元素返回(同時將隊列的頭元素移出隊列)而且使用signal()隨機喚醒一個在入列方法(put方法、offer的超時方法)中阻塞的線程;若是隊列爲空,則直接返回null。 3> poll(long timeout, TimeUnit unit)方法:同take()方法同樣,惟一不一樣的是:take方法是永久等待,而這個方法是超時等待。 LinkedBlockingQueue 1)入列方法: 1> put(E e)方法: 獲取到入列鎖(putLock)後,將元素插入到隊列的尾部,若是插入前隊列已滿,則調用await()阻塞當前線程; 若是插入元素後,隊列未滿,則使用signal()隨機喚醒一個在入列方法(put方法、offer的超時方法)中阻塞的線程。 2> offer(E e)方法: 獲取到入列鎖(putLock)後,將元素插入到隊列的尾部,插入成功返回true,(隊列已滿時)插入失敗返回false。 若是插入元素後,隊列未滿,則使用signal()隨機喚醒一個在入列方法(put方法、offer的超時方法)中阻塞的線程。 3> offer(E e, long timeout, TimeUnit unit)方法:同put()方法同樣,惟一不一樣的是:put方法是永久等待,而這個方法是超時等待。 2)出列方法: 1> take()方法: 獲取到出列鎖(takeLock)後,將隊列的頭元素返回(同時將隊列的頭元素移出隊列),若是獲取前隊列爲空,則調用await()阻塞當前線程; 若是獲取元素後,隊列中仍然有元素存在,則使用signal()隨機喚醒一個在出列方法中(take方法、poll的超時方法)阻塞的線程。 2> poll()方法: 獲取到出列鎖(takeLock)後,將隊列的頭元素返回(同時將隊列的頭元素移出隊列),若是獲取前隊列爲空,則返回null; 若是獲取元素後,隊列中仍然有元素存在,則使用signal()隨機喚醒一個在出列方法中(take方法、poll的超時方法)阻塞的線程。 3> poll(long timeout, TimeUnit unit)方法:同take()方法同樣,惟一不一樣的是:take方法是永久等待,而這個方法是超時等待。