您好,登錄后才能下訂單哦!
這篇文章主要講解了“Java的棧和隊列實例分析”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java的棧和隊列實例分析”吧!
package com.yuzhenc.collection; import java.util.Stack; /** * @author: yuzhenc * @date: 2022-03-20 15:41:36 * @desc: com.yuzhenc.collection * @version: 1.0 */ public class Test26 { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.add("A"); stack.add("B"); stack.add("C"); stack.add("D"); System.out.println(stack);//[A, B, C, D] //判斷棧是否為空 System.out.println(stack.empty());//false //查看棧頂元素,不會移除 System.out.println(stack.peek());//D System.out.println(stack);//[A, B, C, D] //查看棧頂元素,并且移除,即出棧(先進后出) System.out.println(stack.pop());//D System.out.println(stack);//[A, B, C] //入棧,和add方法執行的功能一樣,就是返回值不同 System.out.println(stack.push("E"));//返回入棧的元素 E System.out.println(stack);//[A, B, C, E] } }
ArrayBlockingQueue
: 不支持讀寫同時操作,底層基于數組的;
LinkedBlockingQueue
:支持讀寫同時操作,并發情況下,效率高,底層基于鏈表;
package com.yuzhenc.collection; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.TimeUnit; /** * @author: yuzhenc * @date: 2022-03-20 16:00:22 * @desc: com.yuzhenc.collection * @version: 1.0 */ public class Test27 { public static void main(String[] args) throws InterruptedException { ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(3); //添加元素 //不可以添加null,報空指針異常 //arrayBlockingQueue.add(null); //arrayBlockingQueue.offer(null); //arrayBlockingQueue.put(null); //正常添加元素 System.out.println(arrayBlockingQueue.add("Lili"));//true System.out.println(arrayBlockingQueue.offer("Amy"));//true arrayBlockingQueue.put("Nana");//無返回值 //隊列滿的情況下添加元素 //arrayBlockingQueue.add("Sam");//報非法的狀態異常 //設置最大注阻塞時間,如果時間到了隊列還是滿的,就不再阻塞了 arrayBlockingQueue.offer("Daming", 3,TimeUnit.SECONDS); System.out.println(arrayBlockingQueue);//[Lili, Amy, Nana] //真正阻塞的方法,如果隊列一直是滿的,就一直阻塞 //arrayBlockingQueue.put("Lingling");//運行到這永遠走不下去了,阻塞了 //獲取元素 //獲取隊首元素不移除 System.out.println(arrayBlockingQueue.peek());//Lili //出隊,獲取隊首元素并且移除 System.out.println(arrayBlockingQueue.poll());//Lili System.out.println(arrayBlockingQueue);//[Amy, Nana] //獲取隊首元素,并且移除 System.out.println(arrayBlockingQueue.take());//Amy System.out.println(arrayBlockingQueue);//[Nana] //清空元素 arrayBlockingQueue.clear(); System.out.println(arrayBlockingQueue);//[] System.out.println(arrayBlockingQueue.peek()); System.out.println(arrayBlockingQueue.poll()); //設置阻塞事件,如果隊列為空,返回null,時間到了以后就不阻塞了 System.out.println(arrayBlockingQueue.poll(2,TimeUnit.SECONDS)); //真正的阻塞,隊列為空 //System.out.println(arrayBlockingQueue.take());//執行到這里走不下去了 } }
SynchronousQueue
:方便高效地進行線程間數據的傳送,不會產生隊列中數據爭搶問題;
package com.yuzhenc.collection; import java.util.concurrent.SynchronousQueue; /** * @author: yuzhenc * @date: 2022-03-20 21:06:47 * @desc: com.yuzhenc.collection * @version: 1.0 */ public class Test28 { public static void main(String[] args) { SynchronousQueue sq = new SynchronousQueue(); //創建一個線程,取數據: new Thread(new Runnable() { @Override public void run() { while(true){ try { System.out.println(sq.take()); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); //搞一個線程,往里面放數據: new Thread(new Runnable() { @Override public void run() { try { sq.put("aaa"); sq.put("bbb"); sq.put("ccc"); sq.put("ddd"); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }
PriorityBlockingQueue
:帶優先級的阻塞隊列;
無界的隊列,沒有長度限制,但是在你不指定長度的時候,默認初始長度為11,也可以手動指定,當然隨著數據不斷的加入,底層(底層是數組Object[])會自動擴容,直到內存全部消耗殆盡了,導致 OutOfMemoryError內存溢出 程序才會結束;
不可以放入null元素的,不允許放入不可比較的對象(導致拋ClassCastException
),對象必須實現內部比較器或者外部比較器;
package com.yuzhenc.collection; import java.util.concurrent.PriorityBlockingQueue; /** * @author: yuzhenc * @date: 2022-03-20 21:16:56 * @desc: com.yuzhenc.collection * @version: 1.0 */ public class Test29 { public static void main(String[] args) throws InterruptedException { PriorityBlockingQueue<Human> priorityBlockingQueue = new PriorityBlockingQueue<>(); priorityBlockingQueue.put(new Human("Lili",25)); priorityBlockingQueue.put(new Human("Nana",18)); priorityBlockingQueue.put(new Human("Amy",38)); priorityBlockingQueue.put(new Human("Sum",9)); //沒有按優先級排列 System.out.println(priorityBlockingQueue);//[Human{name='Sum', age=9}, Human{name='Nana', age=18}, Human{name='Amy', age=38}, Human{name='Lili', age=25}] //出列的時候按優先級出列 System.out.println(priorityBlockingQueue.take());//Human{name='Sum', age=9} System.out.println(priorityBlockingQueue.take());//Human{name='Nana', age=18} System.out.println(priorityBlockingQueue.take());//Human{name='Lili', age=25} System.out.println(priorityBlockingQueue.take());//Human{name='Amy', age=38} } } class Human implements Comparable <Human> { String name; int age; public Human() {} public Human(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Human{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(Human o) { return this.age-o.age; }
DelayQueue
:DelayQueue是一個無界的BlockingQueue
,用于放置實現了Delayed接口的對象,其中的對象只能在其到期時才能從隊列中取走;
當生產者線程調用put之類的方法加入元素時,會觸發Delayed接口中的compareTo方法進行排序,也就是說隊列中元素的順序是按到期時間排序的,而非它們進入隊列的順序。排在隊列頭部的元素是最早到期的,越往后到期時間越晚;
消費者線程查看隊列頭部的元素,注意是查看不是取出。然后調用元素的getDelay方法,如果此方法返回的值小0或者等于0,則消費者線程會從隊列中取出此元素,并進行處理。如果getDelay方法返回的值大于0,則消費者線程wait返回的時間值后,再從隊列頭部取出元素,此時元素應該已經到期;
不能將null元素放置到這種隊列中;
DelayQueue能做什么
淘寶訂單業務:下單之后如果三十分鐘之內沒有付款就自動取消訂單;
餓了嗎訂餐通知:下單成功后60s之后給用戶發送短信通知;
關閉空閑連接。服務器中,有很多客戶端的連接,空閑一段時間之后需要關閉之;
緩存。緩存中的對象,超過了空閑時間,需要從緩存中移出;
任務超時處理。在網絡協議滑動窗口請求應答式交互時,處理超時未響應的請求等;
package com.yuzhenc.collection; import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; /** * @author: yuzhenc * @date: 2022-03-20 21:43:32 * @desc: com.yuzhenc.collection * @version: 1.0 */ public class Test30 { //創建一個隊列: DelayQueue<User> dq = new DelayQueue<>(); //登錄游戲: public void login(User user){ dq.add(user); System.out.println("用戶:[" + user.getId() +"],[" + user.getName() + "]已經登錄,預計下機時間為:" + user.getEndTime() ); } //時間到,退出游戲,隊列中移除: public void logout(){ //打印隊列中剩余的人: System.out.println(dq); try { User user = dq.take(); System.out.println("用戶:[" + user.getId() +"],[" + user.getName() + "]上機時間到,自動退出游戲"); } catch (InterruptedException e) { e.printStackTrace(); } } //獲取在線人數: public int onlineSize(){ return dq.size(); } //這是main方法,程序的入口 public static void main(String[] args) { //創建測試類對象: Test30 test = new Test30(); //添加登錄的用戶: test.login(new User(1,"張三",System.currentTimeMillis()+5000)); test.login(new User(2,"李四",System.currentTimeMillis()+2000)); test.login(new User(3,"王五",System.currentTimeMillis()+10000)); //一直監控 while(true){ //到期的話,就自動下線: test.logout(); //隊列中元素都被移除了的話,那么停止監控,停止程序即可 if(test.onlineSize() == 0){ break; } } } } class User implements Delayed { private int id;//用戶id private String name;//用戶名字 private long endTime;//結束時間 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getEndTime() { return endTime; } public void setEndTime(long endTime) { this.endTime = endTime; } public User(int id, String name, long endTime) { this.id = id; this.name = name; this.endTime = endTime; } //只包裝用戶名字就可以 @Override public String toString() { return "User{" + "name='" + name + '\'' + '}'; } @Override public long getDelay(TimeUnit unit) { //計算剩余時間 剩余時間小于0 <=0 證明已經到期 return this.getEndTime() - System.currentTimeMillis(); } @Override public int compareTo(Delayed o) { //隊列中數據 到期時間的比較 User other = (User)o; return ((Long)(this.getEndTime())).compareTo((Long)(other.getEndTime())); } }
package com.yuzhenc.collection; import java.util.Deque; import java.util.LinkedList; /** * @author: yuzhenc * @date: 2022-03-20 22:03:36 * @desc: com.yuzhenc.collection * @version: 1.0 */ public class Test31 { public static void main(String[] args) { /* 雙端隊列: Deque<E> extends Queue Queue一端放 一端取的基本方法 Deque是具備的 在此基礎上 又擴展了 一些 頭尾操作(添加,刪除,獲取)的方法 */ Deque<String> d = new LinkedList<>() ; d.offer("A"); d.offer("B"); d.offer("C"); System.out.println(d);//[A, B, C] d.offerFirst("D"); d.offerLast("E"); System.out.println(d);//[D, A, B, C, E] System.out.println(d.poll());//D System.out.println(d);//[A, B, C, E] System.out.println(d.pollFirst());//A System.out.println(d.pollLast());//E System.out.println(d);//[B, C] } }
感謝各位的閱讀,以上就是“Java的棧和隊列實例分析”的內容了,經過本文的學習后,相信大家對Java的棧和隊列實例分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。