简体   繁体   English

如何根据Element属性从PriorityQueue中删除元素?

[英]How to Remove Elements from PriorityQueue according to a Element Property?

I am try to set Maximum Waiting Time inside my PQueue . 我尝试在我的PQueue设置Maximum Waiting Time This Maximum Waiting Time will check my PQueue automatically if there are any links are waiting more than Maximum Waiting Time to remove it. 如果有任何links等待超过Maximum Waiting Time ,则此Maximum Waiting Time将自动检查我的PQueue I did this changes to my code it is working but it is stopping exactly after removing the links. 我对我的代码进行了这项更改,但它在删除链接后正好停止了。 I want to remove all elements from my PQueue according to waiting time condition. 我想根据等待时间条件从我的PQueue删除所有元素。 Can you tell me what I am missing here ? 你能告诉我这里缺少什么吗?

This is my class: 这是我的班级:

public class MyClass {

    public static PriorityQueue <LinkNodeLight> PQueue = new PriorityQueue <> (); 


    private static Set<String> DuplicationLinksHub = new LinkedHashSet <> ();         

    private static Integer IntraLinkCount = new Integer (0);                 
    private static Integer InterLinkCount = new Integer (0);                 
    private static Integer DuplicationLinksCount = new Integer (0);     
    private static Integer MaxWaitTime = new Integer (60000); // 1 M= 60000 MS


    @SuppressWarnings("null")
    LinkNode deque(){

        LinkNode link = null;
        synchronized (PQueue) {

            link = (LinkNode) PQueue.poll();
            if (link != null) {
                link.setDequeTime(new DateTime());
                if (link.isInterLinks())
                    synchronized (InterLinkCount) {
                        InterLinkCount--;
                        }
                else
                    synchronized (IntraLinkCount) {
                        IntraLinkCount--;
                        }
            }

            synchronized (PQueue) {
                if (link.waitingInQueue()>MaxWaitTime) {

                    link = (LinkNode) PQueue.remove();
                                    System.out.println("*********************************");
                                    System.out.println("This Link is Deopped: " + link);
                                    System.out.println("%%% MaX Waiting Time:" + (MaxWaitTime/60000)+"Min");

                                    System.out.println("*********************************");
                  }
            }
            return link;


        }

Your question is a bit opaque, but if I understand it correctly you want to check your PriorityQueue to see if there are items that have waited longer than a specific time. 您的问题有点不透明,但如果我理解正确,您需要检查您的PriorityQueue以查看是否有等待时间超过特定时间的项目。

Your usage of synchronized on the IntraLinkCount and InterLinkCount is, as has been mentioned already, a bit strange. 正如已经提到的,你在IntraLinkCountInterLinkCount上使用synchronized是有点奇怪的。 There is a fairly unknown alternative, the atomic integer class AtomicInteger (in the package java.util.concurrent.atomic : 有一个相当未知的替代方法,原子整数类AtomicInteger (在java.util.concurrent.atomicjava.util.concurrent.atomic

private static AtomicInteger IntraLinkCount = Integer.valueOf(0);

This will work as you want. 这将按你的意愿工作。

The second problem is that you use the poll() method. 第二个问题是您使用poll()方法。 This will remove the top item from the queue. 这将从队列中删除顶部项目。 Maybe you want to use peek() instead, and then only use remove() if the returned link object satisfies link.waitingInQueue() > MaxWaitTime ? 也许你想要使用peek() ,然后只使用remove()如果返回的链接对象满足link.waitingInQueue() > MaxWaitTime

By the way, your queue will return items according to their "natural ordering". 顺便说一句,你的队列将根据他们的“自然顺序”返回项目。 This means the compareTo method is used, and the "smallest" will be returned from the queue first. 这意味着使用compareTo方法,并且首先从队列返回“最小”。 I think you might want to implement a custom compareTo that puts the longest waiting link first instead? 我想你可能想要实现一个自定义compareTo ,它将最长的等待链接放在第一位?

You could also create your PriorityQueue with a custom Comparator object instead. 您也可以使用自定义Comparator对象创建PriorityQueue

Something like this: 像这样的东西:

public class MyClass {
    public static PriorityQueue<LinkNodeLight> PQueue = new PriorityQueue<>();

    private static AtomicInteger IntraLinkCount = new AtomicInteger(0);
    private static AtomicInteger InterLinkCount = new AtomicInteger(0);

    private static Integer MaxWaitTime = Integer.valueOf(60_000); // 1 M= 60000 MS

    LinkNode deque() {
        LinkNode link = null;

        synchronized (PQueue) {
            link = PQueue.peek();

            if (link != null) {
                link.setDequeTime(LocalDateTime.now());

                if (link.isInterLinks())
                    InterLinkCount.decrementAndGet();
                else
                    IntraLinkCount.decrementAndGet();

                if (link.waitingInQueue() > MaxWaitTime) {
                    link = PQueue.remove();

                    System.out.println("*********************************");
                    System.out.println("This Link is Deopped: " + link);
                    System.out.println("%%% MaX Waiting Time:" + MaxWaitTime / 60000 + "Min");
                    System.out.println("*********************************");

                    return link;
                } else
                    return null;
            }
        }

        return link; // Not sure what you want to return here
    }
}

If you are lucky enough to be on Java 8, some magic like this might be useful instead: 如果你很幸运能够使用Java 8,那么这样的一些魔法可能会有用:

synchronized (PQueue) {
    link = PQueue.stream().filter(node -> node.waitingInQueue() > MaxWaitTime).findFirst().orElse(null);

    if (link != null)
        PQueue.remove(link);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM