javablockingqueue
㈠ java linkedblockingqueue 當前多少條數據
概述
LinkedBlockingQueue是java concurrent包提供的另一個多線程安全的阻塞隊列,與ArrayBlockingQueu相比,此隊列的使用鏈表實現(不熟悉鏈表的同學,請查閱大學的數據結構課本),可以提供高效的並發讀寫性能。
數據結構
鏈表節點
既然是鏈表,那麼肯定少不了節點,節點自然包括節點內容和next指針。jdk開發人員,設計的節點是這樣的:
static class Node<E> {
E item;
/**
* One of:
* - the real successor Node
* - this Node, meaning the successor is head.next
* - null, meaning there is no successor (this is the last node)
*/
Node<E> next;
Node(E x) { item = x; }
}
在這里,用到了java范型的機制,用來保存不同類型的對象。
上述節點,提供了一個構造函數,用來傳入需要保存的內容,這里的構造函數沒有判斷傳入參數是否合法,因為在所有public方法中,已經判斷過了,這里無需進行再次判斷。
鏈表的指針
LInkedBlockingQueue中的鏈表,包含頭指針和尾指針,其中:
頭指針用來管理元素出隊,和 take(), poll(), peek() 三個操作關聯
尾指針用來管理元素入隊,和 put(), offer() 兩個操作關聯
具體的數據結構定義如下:
private transient Node<E> head; /* 頭結點, 頭節點不保存數據信息 */
private transient Node<E> last; /* 尾節點, 尾節點保存最新入隊的數據信息 */
鏈表的容量和大小
LinkedBlockingQueue是有大小限制的,當隊列滿後不能繼續入隊,同時,也有一個變數記錄當前隊列中的元素數量:
private final int capacity; /* 隊列容量一般使用中,構造LinkedBlockingQueue時,需要傳入當前隊列大小,如果不傳入,默認是Integer.MAX_VALUE */
private final AtomicInteger count = new AtomicInteger(0); // 隊列當前大小
注意:這里的count對象,是原子類型,而不是一般的int類型,與ArrayBlockingQueue中的不符,這是因為LinkedBlockingQueue使用讀和寫兩把鎖來控制並發操作,讀和寫可能同時修改count欄位的值,而ArrayBlockingQueue只有一把鎖用於控制讀寫操作,所以count對象是普通的,線程不安全的類型
㈡ java arrayblockingqueue有thread.interrupt機制嗎
正因為LinkedBlockingQueue使用兩個獨立的鎖控制數據同步,所以可以使存取兩種操作並行執行,從而提高並發效率。而ArrayBlockingQueue使用一把鎖,造成在存取兩種操作爭搶一把鎖,而使得性能相對低下。LinkedBlockingQueue可以不設置隊列容量,默認為Integer.MAX_VALUE.其容易造成內存溢出,一般要設置其值。
LinkedBlockingQueue底層的定義如下:
public class LinkedBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
static class Node<E> {
/** The item, volatile to ensure barrier separating write and read */
volatile E item;
Node<E> next;
Node(E x) { item = x; }
}
// 支持原子操作
private final AtomicInteger count = new AtomicInteger(0);
// 鏈表的頭和尾
private transient Node<E> head;
private transient Node<E> last;
㈢ java中blockingqueue怎麼實現非同步處理
JDK 的API 文檔中,有一小例子
~~~~~~~~
㈣ java用BlockingQueue實現任務分配
當然,合理的,這是管理的目標,該公司的目標被分解到各個部門,再由部門分配到每個員工,並達成情況進行考核,而與收入掛鉤。當然,如果你認為點與你的目標有問題,你可以用你的直接上司溝通,獲得支持。
㈤ 多線程的隊列blockqueue如何理解
在Java多線程應用中,隊列的使用率很高,多數生產消費模型的首選數據結構就是隊列。Java提供的線程安全的Queue可以分為阻塞隊列和非阻塞隊列,其中阻塞隊列的典型例子是BlockingQueue,非阻塞隊列的典型例子是ConcurrentLinkedQueue,在實際應用中要根據實際需要選用阻塞隊列或者非阻塞隊列。 註:什麼叫線程安全?這個首先要明確。線程安全就是說多線程訪問同一代碼,不會產生不確定的結果。 LinkedBlockingQueue 由於LinkedBlockingQueue實現是線程安全的,實現了先進先出等特性,是作為生產者消費者的首選,LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的話,默認最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在隊列滿的時候會阻塞直到有隊列成員被消費,take方法在隊列空的時候會阻塞,直到有隊列成員被放進來。
㈥ 關於Java的LinkedBlockingQueue的問題
Procer 中只有一個Proct 實例 p,所以加到Global.list 中的 p 是同一個對象,有可能Procer
在連續的幾個 i ,設置 p 的 name 和 date,加入Global.list,但 p 是同一個對象,所以 name 和 date 都是最後一個 i 的值,然後Consumer 從Global.list 中取數據,取到的是同一個 p 對象,列印出的 name 和date 相同的幾條記錄。
正確的方法應該是Procer 中每次往Global.list 中添加不同的Proct 實例。
classProct{
privateStringname;
privateStringdate;
publicProct(){
super();
}
publicProct(Stringname,Stringdate){
super();
this.name=name;
this.date=date;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicStringgetDate(){
returndate;
}
publicvoidsetDate(Stringdate){
this.date=date;
}
}
classProcerimplementsRunnable{
@Override
publicvoidrun(){
for(inti=0;i<5;++i){
try{
//System.out.println("begintoput:"+i);
Global.list.put(newProct("Name:"+i,"Date"+i));
//System.out.println("endtoput:"+i);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
㈦ 關於JAVA BlockingQueue的工作原理
BlockingQueue 實現是線程安全的。所有排隊方法都可以使用內部鎖或其他形式的並發控制來自動達到它們的目的。然而,大量的 Collection 操作(addAll、containsAll、retainAll 和 removeAll)沒有 必要自動執行,除非在實現中特別說明。因此,舉例來說,在只添加了 c 中的一些元素後,addAll(c) 有可能失敗(拋出一個異常)。
㈧ java中queue和blockingqueue的區別
內容主要來自jdk的api,大家可參考jdkapi1.BlockingQueue:支持兩個附加操作的 Queue,這兩個操作是:檢索元素時等待隊列變為非空,以及存儲元素時等待空間變得可用。
2.BlockingQueue 不接受 null 元素。
3.BlockingQueue 可以是限定容量的。
4.BlockingQueue 實現是線程安全的。Queue不是線程安全的。因此可以將Blockingqueue用於用於生產者-使用者隊列。
根據Api修改的一個例子,大家可以修改自己體驗BlockingQueue的使用
package test;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* 生產者
* @author wasw100
*/
class Procer implements Runnable {
private final BlockingQueue queue;
Procer(BlockingQueue q) {
queue = q;
}
public void run() {
try {
for (int i = 0; i < 3; i++) {
queue.put(proce());
System.out.println("生產後:"+queue.peek());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
Character proce() {
char c = (char) (Math.random() * 26 + 'A');
System.out.println("生產前:" + c);
return c;
}
}
/**
* 消費者
* @author wasw100
*/
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) {
queue = q;
}
public void run() {
try {
while (true) {
consume(queue.take());
//Thread.sleep(100);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
void consume(Character c) {
System.out.println("消費:" + c);
}
}
/**
* 一個生產者、兩個消費者
*
* @author wasw100
*/
class Setup {
public static void main(String[] args) {
BlockingQueue q = new ArrayBlockingQueue(1);
Procer p = new Procer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
㈨ Java中Queue和BlockingQueue的區別
內容主要來自jdk的api,可參考jdkapi1.BlockingQueue:支持兩個附加操作的 Queue,這兩個操作是:檢索元素時等待隊列變為非空,以及存儲元素時等待空間變得可用。
2.BlockingQueue 不接受 null 元素。
3.BlockingQueue 可以是限定容量的。
4.BlockingQueue 實現是線程安全的。Queue不是線程安全的。因此可以將Blockingqueue用於用於生產者-使用者隊列。
根據Api修改的一個例子,大家可以修改自己體驗BlockingQueue的使用
package test;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* 生產者
* @author wasw100
*/
class Procer implements Runnable {
private final BlockingQueue queue;
Procer(BlockingQueue q) {
queue = q;
}
public void run() {
try {
for (int i = 0; i < 3; i++) {
queue.put(proce());
System.out.println("生產後:"+queue.peek());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
Character proce() {
char c = (char) (Math.random() * 26 + 'A');
System.out.println("生產前:" + c);
return c;
}
}
/**
* 消費者
* @author wasw100
*/
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) {
queue = q;
}
public void run() {
try {
while (true) {
consume(queue.take());
//Thread.sleep(100);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
void consume(Character c) {
System.out.println("消費:" + c);
}
}
/**
* 一個生產者、兩個消費者
*
* @author wasw100
*/
class Setup {
public static void main(String[] args) {
BlockingQueue q = new ArrayBlockingQueue(1);
Procer p = new Procer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
㈩ java arrayblockingqueue 什麼時候用
ArrayBlockingQueue
是一個由數組支持的有界阻塞隊列。此隊列按 FIFO(先進先出)原則對元素進行排序。隊列的頭部 是在隊列中存在時間最長的元素。隊列的尾部 是在隊列中存在時間最短的元素。新元素插入到隊列的尾部,隊列獲取操作則是從隊列頭部開始獲得元素。
public class ArrayBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable {
/** 隊列元素 數組 */
private final E[] items;
/** 獲取、刪除元素時的索引(take, poll 或 remove操作) */
private int takeIndex;
/** 添加元素時的索引(put, offer或 add操作) */
private int putIndex;
/** 隊列元素的數目*/
private int count;
/** 鎖 */
private final ReentrantLock lock;
/** 獲取操作時的條件 */
private final Condition notEmpty;
/** 插入操作時的條件 */
private final Condition notFull;
//超出數組長度時,重設為0
final int inc(int i) {
return (++i == items.length)? 0 : i;
}