我正在写一个与硬件通信的应用程序。虽然应用程序可以同时接收和处理多个请求,但硬件不能!单进程阻塞队列
硬件要求这些并行请求基本上组织成线性请求链,每个请求链一个接一个地执行。
我也有一个要求,能够优先考虑请求的优先级,因为有些是后台进程没有紧急性,有些是活的,需要跳到队列的前面以便立即处理。
我对排队没有太多经验,但是如果这样的图书馆不存在,我会感到惊讶。
我正在写一个与硬件通信的应用程序。虽然应用程序可以同时接收和处理多个请求,但硬件不能!单进程阻塞队列
硬件要求这些并行请求基本上组织成线性请求链,每个请求链一个接一个地执行。
我也有一个要求,能够优先考虑请求的优先级,因为有些是后台进程没有紧急性,有些是活的,需要跳到队列的前面以便立即处理。
我对排队没有太多经验,但是如果这样的图书馆不存在,我会感到惊讶。
看到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作为该“锁定获取”进程的队列。 –