A. java 如何實現一個線程安全的隊列
以下是兩個線程:
import java.util.*;
public class Thread_List_Operation {
//假設有這么一個隊列
static List list = new LinkedList();
public static void main(String[] args) {
Thread t;
t = new Thread(new T1());
t.start();
t = new Thread(new T2());
t.start();
}
}
//線程T1,用來給list添加新元素
class T1 implements Runnable{
void getElemt(Object o){
Thread_List_Operation.list.add(o);
System.out.println(Thread.currentThread().getName() + "為隊列添加了一個元素");
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
getElemt(new Integer(1));
}
}
}
//線程T2,用來給list添加新元素
class T2 implements Runnable{
void getElemt(Object o){
Thread_List_Operation.list.add(o);
System.out.println(Thread.currentThread().getName() + "為隊列添加了一個元素");
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
getElemt(new Integer(1));
}
}
}
//結果(亂序)
Thread-0為隊列添加了一個元素
Thread-1為隊列添加了一個元素
Thread-0為隊列添加了一個元素
Thread-1為隊列添加了一個元素
Thread-1為隊列添加了一個元素
Thread-1為隊列添加了一個元素
Thread-1為隊列添加了一個元素
Thread-1為隊列添加了一個元素
Thread-1為隊列添加了一個元素
Thread-1為隊列添加了一個元素
Thread-1為隊列添加了一個元素
Thread-1為隊列添加了一個元素
Thread-0為隊列添加了一個元素
Thread-0為隊列添加了一個元素
Thread-0為隊列添加了一個元素
Thread-0為隊列添加了一個元素
Thread-0為隊列添加了一個元素
Thread-0為隊列添加了一個元素
Thread-0為隊列添加了一個元素
Thread-0為隊列添加了一個元素
B. java有沒有循環隊列 線程安全
jdk沒有線程安全的循環隊列,
ConcurrentLinkedQueue是線程安全非阻塞的隊列
C. JAVA中哪個能同時滿足 先進先出(增減操作非常頻繁)和同步安全的容器集合並在性能上不至於太差
public class ConcurrentLinkedQueue<E>
extends AbstractQueue<E>
implements Queue<E>, Serializable
一個基於鏈接節點的無界線程安全隊列。此隊列按照 FIFO(先進先出)原則對元素進行排序。隊列的頭部 是隊列中時間最長的元素。隊列的尾部 是隊列中時間最短的元素。新的元素插入到隊列的尾部,隊列獲取操作從隊列頭部獲得元素。當多個線程共享訪問一個公共 collection 時,ConcurrentLinkedQueue 是一個恰當的選擇。此隊列不允許使用 null 元素。
此實現採用了有效的「無等待 (wait-free)」演算法,該演算法基於 Maged M. Michael 和 Michael L. Scott 合著的 Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms 中描述的演算法。
需要小心的是,與大多數 collection 不同,size 方法不是 一個固定時間操作。由於這些隊列的非同步特性,確定當前元素的數量需要遍歷這些元素。
此類及其迭代器實現了 Collection 和 Iterator 介面的所有可選 方法。
內存一致性效果:當存在其他並發 collection 時,將對象放入 ConcurrentLinkedQueue 之前的線程中的操作 happen-before 隨後通過另一線程從 ConcurrentLinkedQueue 訪問或移除該元素的操作。
注意:ConcurrentLinkedQueue的size()是要遍歷一遍集合的!因此,若不能滿足你,可以基於 LinkedList(先進先出),自己加上同步,要性能控制住,需要盡可能小力度加同步 。
D. java 什麼情況下使用 並發隊列
並發隊列是一個基於鏈接節點的無界線程安全隊列,它採用先進先出的規則對節點進行排序,當我們添加一個元素的時候,它會添加到隊列的尾部,當我們獲取一個元素時,它會返回隊列頭部的元素。它採用了「wait-free」演算法來實現,該演算法在Michael
& Scott演算法上進行了一些修改。
入隊列
入隊列就是將入隊節點添加到隊列的尾部。為了方便理解入隊時隊列的變化,以及head節點和tair節點的變化,每添加一個節點我就做了一個隊列的快照圖。
publicEpoll(){
Node</e><e>h=head;
//p表示頭節點,需要出隊的節點
Node</e><e>p=h;
for(inthops=0;;hops++){
//獲取p節點的元素
Eitem=p.getItem();
//如果p節點的元素不為空,使用CAS設置p節點引用的元素為null,如果成功則返回p節點的元素。
if(item!=null&&p.casItem(item,null)){
if(hops>=HOPS){
//將p節點下一個節點設置成head節點
Node</e><e>q=p.getNext();
updateHead(h,(q!=null)?q:p);
}
returnitem;
}
//如果頭節點的元素為空或頭節點發生了變化,這說明頭節點已經被另外一個線程修改了。那麼獲取p節點的下一個節點
Node</e><e>next=succ(p);
//如果p的下一個節點也為空,說明這個隊列已經空了
if(next==null){
//更新頭節點。
updateHead(h,p);
break;
}
//如果下一個元素不為空,則將頭節點的下一個節點設置成頭節點
p=next;
}
returnnull;
}
首先獲取頭節點的元素,然後判斷頭節點元素是否為空,如果為空,表示另外一個線程已經進行了一次出隊操作將該節點的元素取走,如果不為空,則使用CAS的方式將頭節點的引用設置成null,如果CAS成功,則直接返回頭節點的元素,如果不成功,表示另外一個線程已經進行了一次出隊操作更新了head節點,導致元素發生了變化,需要重新獲取頭節點。
E. java實現線程安全的隊列
PrintPreviewDialog pPDlg;
exec_prefix='NONE'PACKAGE='libevent'
PACKAGE_BUGREPORT=''
PACKAGE_NAME=''
PACKAGE_STRING=''
PACKAGE_TARNAME=''
PACKAGE_URL=''
PACKAGE_VERSION=''
PATH_SEPARATOR=':'