2015-10-23 25 views
9

PQueue benim Maximum Waiting Time ayarlamaya çalışıyorum. Bu Maximum Waiting Time, linksMaximum Waiting Time'dan daha fazlasını bekliyorsa otomatik olarak PQueue'u kontrol edecektir. Bu değişiklikleri kodumda çalıştım ama bağlantıyı kaldırdıktan hemen sonra duruyor. Tüm öğeleri PQueue'dan bekleme süresi durumuna göre kaldırmak istiyorum. Bana neyi kaçırdığımı söyler misin?Öğe Özelliğine Göre PriorityQueue öğelerini nasıl kaldırılır?

Bu benim sınıftır:

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

tüm kodu ile bakmıyorlar mı

synchronized (PQueue) { link = PQueue.stream().filter(node -> node.waitingInQueue() > MaxWaitTime).findFirst().orElse(null); if (link != null) PQueue.remove(link); } 
, ancak 'InterLinkCount' veya 'IntraLinkCount' üzerinde senkronizasyon çalışmıyor. Bu değişkenlerin hangi nesneye başvurduğunu değiştirmeye devam edersiniz, bu yüzden farklı iş parçacıkları aynı kilitleri alamaz. – user2357112

+0

@ user2357112 Bu benim büyük bir program olduğu için tüm projem değil. Bu onun bir parçası. Gerekirse kodla ilgili diğer prosedürleri sağlayabilirim – medo0070

+0

Genel bir yorum: 'new Integer (n)' kullanmayın, bunun yerine 'Integer.valueOf (n)' kullanın. Bu çok daha verimli. – Tomas

cevap

3

Sorunuz biraz opak, ama doğru anlamak, belirli bir süre daha uzun bekledim öğeleri olup olmadığını görmek için PriorityQueue kontrol etmek istiyorum. synchronized kullanımınız IntraLinkCount ve InterLinkCount'da belirtildiği gibi, biraz garip. paketin java.util.concurrent.atomic yılında oldukça bilinmeyen bir alternatif, atomik tamsayı sınıfı AtomicInteger (vardır:.. istediğiniz kadar

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

Bu çalışacaktır

ikinci sorun poll() yöntemini kullanmasıdır Bu olacak Belki yerine peek() kullanmak istiyorum. kuyruktan üst öğeyi kaldırmak ve sonra tek yol, y tarafından döndürülen bağlantı nesnesi tatmin olmadığını remove()link.waitingInQueue() > MaxWaitTime?

kullanmak kuyruğumuz öğeleri "doğal sipariş" e göre iade edecektir. Bu, compareTo yönteminin kullanıldığı anlamına gelir ve "en küçük", önce sıradan döndürülür. Bunun yerine ilk olarak en uzun bekleyen bağlantısını koyan bir özel compareTo uygulamasını uygulamak isteyebilirsiniz.

Bunun yerine create your PriorityQueue with a custom Comparator nesnesini de uygulayabilirsiniz. Böyle

şey: Eğer Java 8 olacak kadar şanslı iseniz

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

, bu gibi bazı sihirli yerine yararlı olabilir:

+0

Bana göre "MaxWaitTime" ın "int" yerine "Tamsayı" olması için bir neden yok. Ve durağan değişkenler 'final' yapmak zarar vermez… – Holger

+0

Bu kod sorudan kopyalandığı için belki de oradaki yorumu yerine koymalısınız? – Tomas

+0

"Integer" in iki tanesini "AtomicInteger" 'e dönüştürdüğünüzden, sonuncusunu "Interin" in tümünden kurtulmak için' int 'haline dönüştürebilirsiniz. Ancak,' final 'değişkenlerini yapma önerisi hepsi, * özellikle * AtomicInteger's. – Holger

İlgili konular