当前位置: 首页 > 知识库问答 >
问题:

具有动态优先级标志的java队列

沈开畅
2023-03-14

我需要建立一个队列,其中元素将在默认情况下按时间顺序添加和删除。但是,如果客户机为队列设置了优先级标志,我需要能够根据元素的优先级顺序提取元素。

我正在考虑创建一个优先级队列,它由一个映射支持,以优先级顺序跟踪队列索引,基于优先级标志,我可以从映射中提取项目,并从队列中弹出项目。

然而,对于这种方法,问题是,我是默认创建地图,还是只在设置了标志的情况下创建地图(考虑到创建动态地图的成本很高,我倾向于默认创建它)。

请让我知道,如果有一个更好的方式这样做,或者如果有一个现有的实现存在。

import javax.naming.OperationNotSupportedException;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

public class DynamicPriorityQueue<ComparableQueueElement> implements IQueue<ComparableQueueElement> {

    private static final int CONSTANT_HUNDRED = 100;
    private boolean fetchByCustomPriority = false;
    private final ReentrantLock lock;
    private final PriorityQueue<ComparableQueueElement> queue;
    private final PriorityQueue<ComparableQueueElement> customPriorityQueue;

    public DynamicPriorityQueue() {
        this(null);
    }

    public DynamicPriorityQueue(Comparator<ComparableQueueElement> comparator) {
        this.lock = new ReentrantLock();
        this.queue = new PriorityQueue<>(CONSTANT_HUNDRED);
        if (comparator != null)
            this.customPriorityQueue = new PriorityQueue<ComparableQueueElement>(CONSTANT_HUNDRED, comparator);
        else
            this.customPriorityQueue = null;
    }

    public void setFetchByCustomPriority(boolean fetchByCustomPriority) throws OperationNotSupportedException {
        if (this.customPriorityQueue == null)
            throw new OperationNotSupportedException("Object was created without a custom comparator.");

        this.fetchByCustomPriority = fetchByCustomPriority;
    }

    public void push(ComparableQueueElement t) throws InterruptedException {
        if (this.lock.tryLock(CONSTANT_HUNDRED, TimeUnit.MILLISECONDS)) {
            try {
                this.queue.offer(t);
                if (this.customPriorityQueue != null)
                    this.customPriorityQueue.offer(t);
            } finally {
                this.lock.unlock();
            }
        }
    }

    public ComparableQueueElement peek() {
        return this.fetchByCustomPriority ? this.queue.peek()
                : (this.customPriorityQueue != null ? this.customPriorityQueue.peek() : null);
    }

    public ComparableQueueElement pop() throws InterruptedException {
        ComparableQueueElement returnElement = null;
        if (this.lock.tryLock(CONSTANT_HUNDRED, TimeUnit.MILLISECONDS)) {
            try {
                if (this.fetchByCustomPriority && this.customPriorityQueue != null) {
                    returnElement = this.customPriorityQueue.poll();
                    this.queue.remove(returnElement);
                }
                else {
                    returnElement = this.queue.poll();
                    if (this.customPriorityQueue != null) {
                        this.customPriorityQueue.remove(returnElement);
                    }
                }
            } finally {
                this.lock.unlock();
            }
        }
        return returnElement;
    }
}

共有1个答案

商焕
2023-03-14

对我来说,如果您的应用程序有标记频繁变化的需求,实现看起来很好。在这种情况下,两个队列都准备好提供或轮询队列中的对象。虽然它使您的添加操作繁重,但检索速度很快。

但是,如果这些更改并不频繁,那么您可以考虑仅在标志更改时从FIFO队列重新初始化自定义优先级队列。并执行所有的peek,只在一个队列而不是两个队列上提供操作。如果使用FIFO优先级,这将更加有效。如果你这样做了,你的推送操作修改如下-

public void push(ComparableQueueElement t) throws InterruptedException {
    if (this.lock.tryLock(CONSTANT_HUNDRED, TimeUnit.MILLISECONDS)) {
        try {
            this.queue.offer(t);
            if (this.fetchByCustomPriority) // add to customPriorityQueue only when flag is enabled
                this.customPriorityQueue.offer(t);
        } finally {
            this.lock.unlock();
        }
    }
}
 类似资料:
  • 问题内容: 以下是典型的读写器模式(很多读取而很少写入) 我想知道是否有可能优先考虑作家和读者?例如,如果其他线程不断持有读取锁,通常writer可能会等待很长一段时间(也许永远),因此有可能使writer具有更高的优先级,因此只要有writer出现,就可以认为它是高优先级(跳过行)之类的。 问题答案: 按照javadoc的,JDK实现并 不会 有任何读/写器的优先级。但是,如果你使用了“公平”的

  • 注意:我知道可以用比较器创建优先级队列,然后重复调用Add。

  • 我在Java使用PriorityQueue。 我有一个结构如下的对象: 优先考虑的是从最便宜到最贵的成本: 我使用add将对象包含在队列中。 它适用于队列中的每个元素,但我添加的最后一个元素总是位于底部。 我做错了什么?

  • 这些天,我阅读了一些关于和的文档。我了解到Javascript是一个单线程,每次只会执行一段代码。同时,如果有事件发生,它会被推送到事件队列中并阻塞,直到适当的时间。我想知道,当许多事件被阻塞等待同时执行时。这些事件是否具有不同的优先级,因此高优先级事件会在低优先级事件之前执行。或者只是一个FIFO队列。 在上面的代码中,setTimeout fn1将在10 ms发生,Click事件处理程序fn2

  • 我有一个,名为,其中包含类型的对象。 您可以在所有车辆上调用该方法。 我要做的是排序,这样车辆被赋予更高的优先级,并被放在队列的前面。 我假设我必须在这里使用一个比较器,但不知道怎么做。

  • 我需要一个优先级队列,它首先获得具有最高优先级值的项目。我当前正在使用队列库中的PriorityQueue类。但是,这个函数只先返回值最小的项。我尝试了一些很难看的解决方案,比如(sys.maxint-priority)作为优先级,但我只是想知道是否存在更优雅的解决方案。