2015-10-23 13 views
9

मैं को अपने PQueue के अंदर सेट करने का प्रयास कर रहा हूं। यह Maximum Waiting TimePQueue स्वचालित रूप से जांच करेगा यदि linksMaximum Waiting Time से अधिक को हटाने के लिए प्रतीक्षा कर रहे हैं। मैंने अपने कोड में यह परिवर्तन किया है यह काम कर रहा है लेकिन यह लिंक हटाने के ठीक बाद रोक रहा है। मैं प्रतीक्षा समय की स्थिति के अनुसार अपने PQueue से सभी तत्वों को हटाना चाहता हूं। क्या आप मुझे बता सकते हैं कि मैं यहां क्या खो रहा हूं?एक प्राथमिक संपत्ति के अनुसार प्राथमिकता Queue से तत्व कैसे निकालें?

यह मेरी कक्षा है:

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; 


     } 
+0

अपने सभी कोड के माध्यम से देखा नहीं है, लेकिन 'InterLinkCount' या' IntraLinkCount' पर सिंक्रनाइज़ करना काम नहीं करता है। आप बदलते रहते हैं कि वेरिएबल्स किस ऑब्जेक्ट को संदर्भित करते हैं, इसलिए अलग-अलग धागे एक ही ताले को प्राप्त नहीं करते हैं। – user2357112

+0

@ user2357112 यह मेरी पूरी परियोजना नहीं है क्योंकि यह एक बड़ा कार्यक्रम है। यह इसका एक हिस्सा है। यदि आवश्यक हो तो मैं कोड के संबंध में अन्य प्रक्रियाएं प्रदान कर सकता हूं – medo0070

+0

एक सामान्य टिप्पणी: 'Integer.valueOf (n)' का उपयोग करने के बजाय 'नया इंटीजर (एन)' का उपयोग न करें। यह बहुत अधिक कुशल है। – Tomas

उत्तर

3

आपका प्रश्न थोड़ा अपारदर्शी है, लेकिन अगर मैं इसे सही ढंग से समझते हैं कि आप अपने PriorityQueue जाँच करने के लिए अगर वहाँ आइटम है कि एक विशिष्ट समय से अधिक समय बीत चुके हैं देखना चाहते हैं।

IntraLinkCount और InterLinkCount पर आपका उपयोग पहले से ही उल्लेख किया गया है, जैसा कि पहले से ही उल्लेख किया गया है, थोड़ा अजीब है। एक काफी अज्ञात विकल्प, परमाणु पूर्णांक वर्ग AtomicInteger (पैकेज java.util.concurrent.atomic में नहीं है:।।

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

इस के रूप में आप चाहते हैं काम करेंगे

दूसरी समस्या यह है कि आप poll() विधि का उपयोग है यह होगा कतार से शीर्ष आइटम को हटा दें। हो सकता है कि आप के बजाय peek() उपयोग करना चाहते हैं, और उसके बाद ही remove() अगर लौटे लिंक वस्तु को संतुष्ट करता है link.waitingInQueue() > MaxWaitTime?

का उपयोग जिस तरह से, वाई तक हमारी कतार वस्तुओं को उनके "प्राकृतिक क्रम" के अनुसार वापस कर देगी। इसका मतलब है कि compareTo विधि का उपयोग किया जाता है, और "सबसे छोटा" कतार से पहले वापस किया जाएगा। मुझे लगता है कि आप एक कस्टम compareTo लागू करना चाहते हैं जो सबसे लंबे समय तक प्रतीक्षा लिंक को इसके बजाय पहले रखता है?

आप इसके बजाय create your PriorityQueue with a custom Comparator ऑब्जेक्ट भी कर सकते हैं।

कुछ इस तरह:

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 
    } 
} 

आप भाग्यशाली जावा 8 पर हो रहे हैं, तो इस तरह की कुछ जादू बजाय उपयोगी हो सकता है:

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

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

ऐसा लगता है कि 'intWaitTime'' int 'के बजाय 'Integer' होने का कोई कारण नहीं है। और स्थैतिक चर 'अंतिम' को चोट पहुंचाने से कोई दिक्कत नहीं होगी ... – Holger

+0

चूंकि उस कोड को प्रश्न से कॉपी किया गया है, तो आपको इसके बजाय वहां टिप्पणी करनी चाहिए? – Tomas

+0

चूंकि आपने पहले से ही 'इंटेगर' को 'परमाणु इंटेगर' में परिवर्तित कर दिया है, इसलिए आप सभी 'इंटीगर' से छुटकारा पाने के लिए अंतिम व्यक्ति को 'int' में परिवर्तित कर सकते हैं ... हालांकि, चर' अंतिम 'बनाने की सिफारिश पर लागू होता है उनमें से सभी, * विशेष रूप से * 'परमाणु इंटेगर'। – Holger

संबंधित मुद्दे