java - 单进程阻塞队列

标签 java queue message-queue priority-queue

我正在编写一个与硬件通信的应用程序。虽然应用程序可以同时并行接收和处理多个请求,但硬件却不能!

硬件要求这些并行请求基本上被组织成一个线性请求链,每个请求一个接一个地执行。

我还需要能够对请求进行优先级排序,因为有些是不紧急的后台进程,有些是实时进程,需要跳到队列前面进行立即处理。

我对队列没有太多经验,但是如果这样的库还不存在,我会感到惊讶。

最佳答案

参见https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html

我建议对您的请求使用包装器,该包装器具有专门针对该队列的优先级值。例如,您可以使用 Long 作为该值,在其中计算

value = timestamp % N * priorityLevel 

N 取决于您处理事件所需的时间

priorityLevel 是值,越低意味着越紧急(大于零)

<小时/>

编辑:在评论中指定之后

看来您需要创建实例 ThreadPoolExecutor 并将其传递给您自己的队列,该队列将是 PriorityBlockingQueue 的实例。您放入此池中的任务需要执行 Comparable这将按执行优先级对它们进行排序。

参见位old reference ,但作为灵感应该足够了。

<小时/>

编辑:建议的优先级函数对于较小的 N 来说是危险的,现在看看数字,在发生溢出之前,long 可以相乘很多,所以离开模数将起到越来越小的作用,特别是如果你只有两个优先级(抱歉神秘化)

<小时/>

编辑:实现建议的解决方案

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

关于java - 单进程阻塞队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30527960/

相关文章:

c++ - 如何在 C++ 中创建函数指针队列

ios - Objective-C dispatch_after 有时会早于指定时间执行

Java:如何让 while 循环仅输出最后一行

java - 打开相同的 wav 文件给我一个 javax.sound.sampled.LineUnavailableException

java - 按钮没有反应

c# - MSMQ 接收事务 - 回滚不使消息再次可用

ruby-on-rails - Ruby on Rails 中的消息队列

java - Android Realm Retrofit 关系错误

c++ - 当队列不为空时,在queue.front()处为"deque iterator not dereferencable"

c++ - 如何在 ZMQ 中为 (X)PUB/(X)SUB 消息传递实现代理/代理?