2015-05-29 208 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