首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单进程阻塞队列

单进程阻塞队列
EN

Stack Overflow用户
提问于 2015-05-29 11:05:40
回答 3查看 334关注 0票数 1

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

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

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

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-29 11:12:37

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

我建议对具有优先级值的请求使用包装器,特别是对于这个队列。例如,您可以使用该值来计算

代码语言:javascript
复制
value = timestamp % N * priorityLevel 

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

priorityLevel是指较低的值意味着更紧急(大于零)

编辑:注释中的规范后

您似乎需要创建ThreadPoolExecutor实例并将其传递给您自己的队列,这将是PriorityBlockingQueue的实例。放入这个池中的任务需要实现可比的,它将根据它们的执行优先级对它们进行排序。

见位旧参考,但作为灵感应该是足够的。

编辑:建议的优先级函数对较小的N是危险的,现在看数字,在溢出发生之前,长可以乘以很多,所以离开模出会越来越少,特别是当你只有两个优先级级别时(抱歉,迷惑了)

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

代码语言:javascript
复制
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) {}
    }
}

创建的任务的结果是

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2015-06-01 10:03:16

如果您已经熟悉PriorityBlockingQueue,为什么不直接轮询它来处理硬件请求呢?

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2015-06-02 07:27:19

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

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

见关于代码评审的答案

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30527960

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档