在Java中隊列是基于Queue這個接口敛劝,不同的實現(xiàn)類有不同的性質丐黄,不是用數組就是用鏈表實現(xiàn)巍佑。
1茴迁、先看下這個接口提供的方法都有哪些,再具體看實現(xiàn)句狼。
1)boolean add(E e);如果容量不達上限笋熬,將元素插入隊列,并返回true腻菇。
2)boolean offer(E e);如果容量不達上限胳螟,將元素插入隊列,并返回true筹吐。當使用capacity-restricted queue時優(yōu)于add方法糖耸,這個capacity-restricted queue是什么呢?后續(xù)看下丘薛。
3)E remove();返回隊列頭元素嘉竟,并刪除。為空報NoSuchElementException異常洋侨。
4)E poll();返回隊列頭元素舍扰,并刪除。
5)E element();返回隊列頭元素希坚,但是不刪除边苹。為空報NoSuchElementException異常。
6)E peek();返回隊列頭元素裁僧,但是不刪除个束。
2、Queue有兩個接口BlockingQueue和Deque聊疲,Deque是兩端都能增刪的實現(xiàn)茬底,即有隊列的性質又有棧的性質,搞懂Queue获洲,Deque也差不多了阱表。
1)ArrayBlockingQueue基于數組實現(xiàn)
offer方法簡單易懂,用了ReentrantLock贡珊,說明是線程安全最爬,容量定長,超出返回false飞崖,用putIndex變量記錄每次添加的下標烂叔,超出長度重置為0。
但是這個notEmpty.signal()干啥用的固歪?有signal就有await蒜鸡,在這個類上搜下
poll方法也是線程安全的忘朝,每次獲取得下標用takeIndex維護,初始值為0判帮,超出隊列長度重置局嘁。
總結下BlockingQueue定義的方法吧
1溉箕、void put(E e) throws InterruptedException;將元素插入隊列,如果隊列滿了就等待悦昵。這個應該是offer方法被占用實現(xiàn)了不等待的邏輯肴茄,但是干嘛取名put,來個offerWaitIfEmpty()多好。
2但指、boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;將元素插入隊列寡痰,如果隊列滿了就等待傳入的時間。
3棋凳、E take() throws InterruptedException;
4拦坠、poll(long timeout, TimeUnit unit) throws InterruptedException;意義上是take的重載方法,加了等待的超時間剩岳。
5贞滨、int remainingCapacity();返回可用容量。
6卢肃、int drainTo(Collection<? super E> c);將當前隊列的值全部轉移到傳入c中疲迂。另一個重載方法是可以限定轉移的最大條數。
2)DelayQueue莫湘。
LinkedBlockingQueue這個就不講了尤蒿,鏈表實現(xiàn),源碼解讀沒什么難度幅垮。
DelayQueue是延時隊列腰池,添加元素的時候可以設置時間,獲取時候只能獲取到過期的元素忙芒。
jdk居然沒有給demo示弓,參考定時任務寫個demo吧
public class DelayQueueDemo {
public static void main(String[] args) throws InterruptedException {
DelayQueue<DelayDemo> delayeds = new DelayQueue<>();
System.out.println("執(zhí)行開始時間:" + new Date());
delayeds.offer(new DelayDemo(1, TimeUnit.SECONDS, "線程1"));
delayeds.offer(new DelayDemo(2, TimeUnit.SECONDS, "線程2"));
delayeds.offer(new DelayDemo(3, TimeUnit.SECONDS, "線程3"));
DelayDemo take;
while ((take = delayeds.take()) != null) {
new Thread(take).start();
}
}
}
class DelayDemo implements Delayed, Runnable {
private long time;
private String threadName;
public DelayDemo(long time, TimeUnit unit, String threadName) {
this.time = triggerTime(time, unit);
this.threadName = threadName;
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(time - now(), NANOSECONDS);
}
@Override
public int compareTo(Delayed o) {
long diff = getDelay(NANOSECONDS) - o.getDelay(NANOSECONDS);
return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
}
final long now() {
return System.nanoTime();
}
@Override
public void run() {
System.out.println("當前線程為:" + threadName + "," + "當前時間為:" + new Date());
}
private long triggerTime(long delay, TimeUnit unit) {
return triggerTime(unit.toNanos((delay < 0) ? 0 : delay));
}
long triggerTime(long delay) {
return now() + delay;
}
}
未完待續(xù)。呵萨。