摘要:我們將使用單個線程管理任務放入隊列的操作以及從隊列中取出的操作。同時這個線程會持續的管理隊列。另一個線程將用來創建,它將一直運行知道服務器終止。此線程永遠不會過期,有助于實現持續監控。這些請求將會自動的被獲取,并在線程中繼續處理。
在Java中,BlockingQueue接口位于java.util.concurrent包下。阻塞隊列主要用來線程安全的實現生產者-消費者模型。他們可以使用于多個生產者和多個消費者的場景中。
我們可以在各種論壇和文章中找到BlockingQueue的范例。在這篇文章中,我們將介紹如何持續管理隊列中的請求,以及如何在請求進入隊列后立刻處理。
我們將使用單個線程管理任務放入隊列的操作以及從隊列中取出的操作。同時這個線程會持續的管理隊列。另一個線程將用來創建BlockingQueue,它將一直運行知道服務器終止。
阻塞隊列的大小可以在對象初始化的時候設置。它的大小應該基于系統堆的大小。
現在,讓我們回顧創建阻塞隊列的步驟以及如何持續的管理和處理請求。
Step 1: EventData新建一個EventData的POJO類,它會存儲生產者產生的事件數據并輸入到隊列中 - 同時它會被消費者從隊列中取出e并處理。
package com.dzone.blockingqueue.example; class EventData { private String eventID; private String eventName; private String eventDate; private String eventType; private String eventLocation; public String getEventID() { return eventID; } public void setEventID(String eventID) { this.eventID = eventID; } public String getEventName() { return eventName; } public void setEventName(String eventName) { this.eventName = eventName; } public String getEventDate() { return eventDate; } public void setEventDate(String eventDate) { this.eventDate = eventDate; } public String getEventType() { return eventType; } public void setEventType(String eventType) { this.eventType = eventType; } public String getEventLocation() { return eventLocation; } public void setEventLocation(String eventLocation) { this.eventLocation = eventLocation; } }Step 2: QueueService
創建一個QueueService單例類,用來將請求放入隊列中,以及從隊列中提取請求并處理。
package com.dzone.blockingqueue.example; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class QueueService { private static QueueService instance = null; private static BlockingQueue < EventData > eventQueue = null; private QueueService() {} public static QueueService getInstance() { if (instance == null) { instance = new QueueService(); } return instance; } private void initialize() { if (eventQueue == null) { eventQueue = new LinkedBlockingQueue(); EventProcessor eventProcessor = new EventProcessor(); eventProcessor.start(); } } public void putEventInQueue(EventData eventData) { try { initialize(); eventQueue.put(eventData); } catch (InterruptedException ex) { ex.printStackTrace(); } } class EventProcessor extends Thread { @Override public void run() { for (;;) { EventData eventData = null; try { eventData = eventQueue.take(); System.out.println("Process Event Data : Type : " + eventData.getEventType() + " / Name : " + eventData.getEventName()); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } }
我們新建了一個靜態的BlockingQueue變量。它在初始化時會比初始化為ArrayBlockingQueue或是LinkedBlockingQueue,這取決于需求。在此之后,這個對象會被用來放入或是提取請求。
我們還新建了一個繼承了Thread的EventProcessor私有類。它在BlockingQueue初始化的時候啟動。在EventProcessor中使用了一個for循環來管理隊列。BlockingQueue的優點在于它會在沒有元素的時候進入等待模式。當隊列為空時,for循環不會繼續遍歷。當請求進入隊列后,BlockingQueue會繼續運行并處理請求。
單個EventProcessor線程將處理特定隊列中的所有請求。此線程永遠不會過期,有助于實現持續監控。
我們還在QueueService中創建了一個公有的putEventInQueue方法,它會幫助我們將請求放入由getInstance方法獲取的隊列中。在這個方法里,請求被放入BlockingQueue。這些請求將會自動的被BlockingQueue獲取,并在EventProcessor線程中繼續處理。
Step 3: EventService現在讓我們向隊列中加載數據。我們已經實現了一個EventService類。它會將幾個請求寫入BlockingQueue中。在QueueService中,我們會看到請求是如何被取出并處理的。
package com.dzone.blockingqueue.example; public class EventService { public static void main(String arg[]) { try { EventData event = null; for (int i = 0; i < 100; i++) { event = new EventData(); event.setEventType("EventType " + i); event.setEventName("EventName " + i); QueueService.getInstance().putEventInQueue(event); Thread.sleep(100); } } catch (InterruptedException e) { e.printStackTrace(); } } }Step 4: EventProcessor Output
輸出結果如下:
Process Event Data : Type : EventType 0 / Name : EventName 0 Process Event Data : Type : EventType 1 / Name : EventName 1 Process Event Data : Type : EventType 2 / Name : EventName 2 Process Event Data : Type : EventType 3 / Name : EventName 3 Process Event Data : Type : EventType 4 / Name : EventName 4
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注我的微信公眾號!將會不定期的發放福利哦~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68732.html
摘要:如果我們的容器使用,文件如下在這個例子中,我們可以重復創建和銷毀,同一個持久存儲會被提供給新的,無論容器位于哪個節點上。 前言 臨時性存儲是容器的一個很大的買點。根據一個鏡像啟動容器,隨意變更,然后停止變更重啟一個容器。你看,一個全新的文件系統又誕生了。 在docker的語境下: # docker run -it centos [root@d42876f95c6a /]# echo H...
摘要:如果我們的容器使用,文件如下在這個例子中,我們可以重復創建和銷毀,同一個持久存儲會被提供給新的,無論容器位于哪個節點上。 前言 臨時性存儲是容器的一個很大的買點。根據一個鏡像啟動容器,隨意變更,然后停止變更重啟一個容器。你看,一個全新的文件系統又誕生了。 在docker的語境下: # docker run -it centos [root@d42876f95c6a /]# echo H...
摘要:讀取出數據時,將此版本號一同讀出,之后更新時,對此版本號加一。此時,將提交數據的版本數據與數據庫表對應記錄的當前版本信息進行比對,如果提交的數據版本號大于數據庫表當前版本號,則予以更新,否則認為是過期數據。 前言 很多人都在討論數據的指數型增長,以及我們將會有比想象的還要大的數據量。但是,很少有人從數據庫的角度談論這個問題。隨著數據量的暴漲,數據庫也需要隨之升級。這也是為什么既要了解如...
摘要:根本上來說,這意味著不僅要將整個應用程序分解,而且要將任何一個服務器中的各個部分分解為多個模塊化容器,這些容器易于參數化和重復使用。在中,這種模塊化容器服務的實施者是。一個是指一組共享文件系統,內核命名空間和地址的一組容器。 過去幾年容器逐漸成為了打包和部署代碼的流行的方式。容器鏡像解決很多現有的打包和部署工具所帶來的問題,初次以外,還為我們提供了構建分布式應用的全新的思路。就如SOA...
閱讀 1104·2021-11-16 11:45
閱讀 3124·2021-10-13 09:40
閱讀 714·2019-08-26 13:45
閱讀 1188·2019-08-26 13:32
閱讀 2167·2019-08-26 13:23
閱讀 911·2019-08-26 12:16
閱讀 2823·2019-08-26 11:37
閱讀 1748·2019-08-26 10:32