2015-05-29 153 views
1

我正在寫一個與硬件通信的應用程序。雖然應用程序可以同時接收和處理多個請求,但硬件不能!單進程阻塞隊列

硬件要求這些並行請求基本上組織成線性請求鏈,每個請求鏈一個接一個地執行。

我也有一個要求,能夠優先考慮請求的優先級,因爲有些是後臺進程沒有緊急性,有些是活的,需要跳到隊列的前面以​​便立即處理。

我對排隊沒有太多經驗,但是如果這樣的圖書館不存在,我會感到驚訝。

+0

編碼問題是什麼?並且,獲取硬件所服務的隊列前面的單個進程/對象的鎖定。 –

+0

@shekhar蘇曼絕對沒有。但在探索已經存在的東西之前,我不想重新發明輪子! – tarka

+0

@ tarka-我的意思是說併發API可以幫助您逐個訪問硬件資源。請參閱「Java Concurrent API」,並且您已經在討論如何使用Priority Queue作爲該「鎖定獲取」進程的隊列。 –

回答

0

看到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 
+0

OP實際上已經知道優先級隊列,他/她正在詢問關於如何完成工作的庫/方法。我不確定你的答案是否符合他/她的目的... –

+0

@shekharsuman OP表明他熟悉「PriorityQueue」嗎? – Kayaman

+0

@ Kayaman - 檢查問題是否使用此「Priority-Queue」標記。這意味着OP已經知道這一點。 –

0

如果你已經熟悉了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.... 
    } 
} 
0

以下所有有用的評論和答案我確定可能沒有預先構建的解決方案。爲了嘗試提供一個全面的答案,我已經用PriorityBlockingQueue編寫了自己的實現。

我在StackExchange Code Review上發佈了代碼,您可以看到完整的代碼和任何社區提出的改進建議。

See answer on code review