【问题标题】:Single process blocking queue单进程阻塞队列
【发布时间】:2015-08-12 05:23:24
【问题描述】:

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

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

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

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

【问题讨论】:

  • 编码一有什么问题?并且,获取队列前面的单个进程/对象的锁定,您要取出该队列以供硬件服务。
  • @shekhar suman 绝对没有。但我不想在探索已经存在的东西之前重新发明轮子!
  • @tarka- 我的意思是说并发 API 可以帮助您允许一对一地访问硬件资源。看,Java Concurrent API,您已经在谈论使用优先队列作为lock-acquiring 进程的队列。

标签: java queue message-queue priority-queue


【解决方案1】:

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

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

value = timestamp % N * priorityLevel 

N 取决于您处理事件需要多长时间

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


编辑:在 cmets 中指定后

您似乎需要创建 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

【讨论】:

  • OP 实际上已经知道优先级队列,他/她正在询问如何完成工作的库/方法。我不确定你的回答是否符合他/她的目的......
  • @shekharsuman OP在哪里表明他熟悉PriorityQueue
  • @Kayaman-检查问题是否带有此Priority-Queue 的标签。这意味着 OP 已经知道这一点。
  • 从问题上的标签,很明显OP应该能找到它,但从问题本身来看,他似乎并不知道。
  • 我知道但不熟悉priority queue。我正在尝试确定这是否确实是该工作的正确工具,以及是否有更好/不同/推荐的方法使用已经处理过的现有工具或库或陷阱来解决此问题。
【解决方案2】:

如果您已经熟悉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....
    }
}

【讨论】:

    【解决方案3】:

    根据所有有用的 cmets 和答案,我确定可能没有针对此问题的预构建解决方案。为了尝试为这个问题提供一个全面的答案,我尝试使用 PriorityBlockingQueue 编写自己的实现。

    我在StackExchange Code Review 上发布了代码,你可以看到完整的代码和任何社区建议的改进。

    See answer on code review

    【讨论】:

      猜你喜欢
      • 2014-10-16
      • 2017-09-13
      • 2019-07-08
      • 2019-02-12
      • 1970-01-01
      • 2018-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多