我正在寫一個與硬件通信的應用程序。雖然應用程序可以同時接收和處理多個請求,但硬件不能!單進程阻塞隊列
硬件要求這些並行請求基本上組織成線性請求鏈,每個請求鏈一個接一個地執行。
我也有一個要求,能夠優先考慮請求的優先級,因爲有些是後臺進程沒有緊急性,有些是活的,需要跳到隊列的前面以便立即處理。
我對排隊沒有太多經驗,但是如果這樣的圖書館不存在,我會感到驚訝。
我正在寫一個與硬件通信的應用程序。雖然應用程序可以同時接收和處理多個請求,但硬件不能!單進程阻塞隊列
硬件要求這些並行請求基本上組織成線性請求鏈,每個請求鏈一個接一個地執行。
我也有一個要求,能夠優先考慮請求的優先級,因爲有些是後臺進程沒有緊急性,有些是活的,需要跳到隊列的前面以便立即處理。
我對排隊沒有太多經驗,但是如果這樣的圖書館不存在,我會感到驚訝。
看到https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html
我會建議使用的包裝爲您的要求具有優先權值專爲這一隊列。舉例來說,你能長時間使用爲值,您計算
value = timestamp % N * priorityLevel
N是依賴於它需要你多久才能處理您的活動
priorityLevel是值,其中下部裝置更爲迫切(大於零)
編輯:在註釋中說明之後
好像你需要創建 ThreadPoolExecutor 的實例,並將它傳遞給您自己的隊列,該隊列將是PriorityBlockingQueue的實例。您放入此池的任務需要執行Comparable,它們將按執行優先級排序。
見位old reference,但作爲靈感應該是足夠的。
編輯:建議優先功能是很危險的小N,現在看到的數字,長的可以成倍很多之前溢出會發生,所以離開模出無助少,特別是如果你有隻有兩個優先級(大約神祕對不起)
編輯:實施建議的解決方案的
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class QTest {
public static void main(String[] args){
//create executor with exactly one thread (first four arguments) that is
//using priority queue to store tasks (it takes care of sorting by priority)
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, new PriorityBlockingQueue());
executor.execute(new EventWrapper(1, "A"));
executor.execute(new EventWrapper(2, "B"));
executor.execute(new EventWrapper(1, "C"));
executor.execute(new EventWrapper(3, "D"));
executor.execute(new EventWrapper(1, "E"));
//just to have it terminated once test is done
executor.shutdown();
}
}
//in this wrapper should be loaded anything you want to have executed
class EventWrapper implements Comparable<EventWrapper>, Runnable{
public final long priority;
//name just to recognize what is being executed
public final String name;
public EventWrapper(int priority, String name){
//priority function out of current time, can be obviously inserted from elsewhere
this.priority = priority*System.currentTimeMillis();
this.name = name;
}
@Override
public int compareTo(EventWrapper that) {
//lower priority first
if(this.priority==that.priority)return 0;
return this.priority>that.priority?1:-1;
}
@Override
public void run() {
System.out.println("Executing task "+name+" with priority "+priority);
//sleep to rule out speed of insertion in executor
try {Thread.sleep(1000);
} catch (InterruptedException ex) {}
}
}
結果爲創建的任務是
Executing task A with priority 1433276819484
Executing task C with priority 1433276819485
Executing task E with priority 1433276819485
Executing task B with priority 2866553638970
Executing task D with priority 4299830458455
OP實際上已經知道優先級隊列,他/她正在詢問關於如何完成工作的庫/方法。我不確定你的答案是否符合他/她的目的... –
@shekharsuman OP表明他熟悉「PriorityQueue」嗎? – Kayaman
@ Kayaman - 檢查問題是否使用此「Priority-Queue」標記。這意味着OP已經知道這一點。 –
如果你已經熟悉了PriorityBlockingQueue
,你爲什麼不乾脆輪詢它來處理硬件的要求?
public class HardwareHandler
public static final PriorityBlockingQueue<Message> queue =
new PriorityBlockingQueue<Message>();
static {
while (true) {
Message m = queue.take();
handleMessage(m);
}
}
private static void handleMessage(Message m) {
// handle message....
}
}
以下所有有用的評論和答案我確定可能沒有預先構建的解決方案。爲了嘗試提供一個全面的答案,我已經用PriorityBlockingQueue
編寫了自己的實現。
我在StackExchange Code Review上發佈了代碼,您可以看到完整的代碼和任何社區提出的改進建議。
編碼問題是什麼?並且,獲取硬件所服務的隊列前面的單個進程/對象的鎖定。 –
@shekhar蘇曼絕對沒有。但在探索已經存在的東西之前,我不想重新發明輪子! – tarka
@ tarka-我的意思是說併發API可以幫助您逐個訪問硬件資源。請參閱「Java Concurrent API」,並且您已經在討論如何使用Priority Queue作爲該「鎖定獲取」進程的隊列。 –