Queue: (數組,鏈表) ConcurrentLinkedQueue
import java.util.Queue;
import java.util.concurrent.*;
public class QueueTest {
private static Queue<String> total = new ConcurrentLinkedQueue<>();//單向隊列
private static Queue<String> total1 = new ConcurrentLinkedDeque<>();//雙向隊列
/**
* 非併發,不加鎖:ArrayList,LinkedList
* 併發小:Collections.synchronizedXXX
* 讀取量特別大,寫入量特別少:CopyOnWriteXXXX
* 高併發用的多的隊列
* Queue:
* ConcurrentLinkedQueue 併發加鎖,非阻塞
* BlockingQueue: 阻塞隊列 put如果滿了,新線程進來就會等待; take如果拿了,新線程進來就會等待
* LinkedBlockingQueue:無界隊列
* ArrayBlockingQueue:有界隊列;
* 如果隊列已經滿了:
* add : 再加入數據會報異常
* offer : 再加入數據不會報異常,但不會加入(offer還可以設置,如果多少時間內加不進去則不再加入 pp.offer("aaa",1,TimeUnit.SECONDS))
* put : 加不進去,則線程阻塞
* DelayQueue:非阻塞,無界隊列 可以設置每個存入的數據多少時間後可以取出。每個元素需要實現Delayed類,以及實現相應方法。可以用來做定時執行任務
* TransferQueue: 先啓動消費者,再賦值
* LinkedTransferQueue:
* SynchronousQueue : 容量爲0的隊列,立馬交給消費者消費
*/
static {
for (int i=0;i<10000;i++) total.add("火車票 編號:"+(i+1));
}
public static void main(String[] args) throws Exception{
// for (int i = 0;i<10;i++){
// new Thread(()->{
// while (true){
// String s = total.poll();
// if ( s == null) break;
// else System.out.println(s);
// }
// }).start();
// }
//new QueueTest1().test2();
// new QueueTest1().test3();
new QueueTest1().test4();
}
}
class QueueTest1{
void test(){
Queue<String> queue = new ConcurrentLinkedQueue<>();
queue.offer("hello"); //類似於 add。 但ArrayList 元素最多有個數限制。但offer可以通過返回值判斷是否加入,是無界隊列,FIFO
String s1 = queue.peek(); //取出一個數據
String s2 = queue.poll(); //刪除一個數據,並把刪除的數據返回
}
void test2() throws InterruptedException {
BlockingQueue queue = new DelayQueue<>();
TTT t1 = new TTT(1000L);
TTT t2 = new TTT(2000L);
TTT t3 = new TTT(3000L);
queue.put(t3);
queue.put(t2);
queue.put(t1);
System.out.println(queue);
for (int i = 0;i<3;i++) System.out.println(queue.take());
}
class TTT implements Delayed{
private Long waitTime;
public TTT(Long waitTime) {
this.waitTime = waitTime;
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(waitTime - System.currentTimeMillis(),TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
if (this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)) return -1;
else if (this.getDelay(TimeUnit.MILLISECONDS) == o.getDelay(TimeUnit.MILLISECONDS)) return 0;
else return 0;
}
@Override
public String toString() {
return "TTT{" +"waitTime=" + waitTime + '}';
}
}
//實時消息處理用的多
void test3(){
TransferQueue<String> queue = new LinkedTransferQueue();
new Thread(() ->{
try {
System.out.println(queue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
try {
queue.transfer("123"); //找不到消費者,線程將阻塞在這裏
// queue.add("123"); //不會阻塞
// queue.put("123");//不會阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
// new Thread(() ->{
// try {
// System.out.println(queue.take());
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }).start();
}
void test4() throws InterruptedException {
BlockingQueue<String> queue = new SynchronousQueue<>();
new Thread(()->{
try {
queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
queue.put("aaa");//沒有消費者則阻塞
// queue.add("aaa"); //會報錯 java.lang.IllegalStateException: Queue full
System.out.println(queue.size());
}
}