2010-10-28 13 views
5

क्या ब्लॉकिंग कतार का कोई कार्यान्वयन है जो निष्पक्ष ले() ऑपरेशन की गारंटी देता है यदि एकाधिक उपभोक्ता एक ही कतार से तत्व को हटा रहे हैं। मैंने LinkedBlockingQueue, LinkedTransferQueue की जांच की और ऐसा लगता है कि उनमें से दोनों अनुचित हैं। ArrayBlockingQueue निष्पक्ष ऑपरेशन प्रदान करता है लेकिन इसकी बाध्यता है।क्या जावा में कोई भी (असंबद्ध) मेला अवरुद्ध कतार है?

+2

ConcurrentLinkedList के बारे में क्या? (ठीक है, यह प्रति कहने वाला 'कतार' नहीं है ... और मुझे यकीन नहीं है कि यह और अधिक 'निष्पक्ष' है) –

उत्तर

0

निष्पक्षता नीति SynchronousQueue लिए निर्दिष्ट किया जा सकता है:

एक कतार निष्पक्षता के साथ निर्माण किया फीफो क्रम में सही अनुदान के लिए सेट का उपयोग कर सकते धागे

+2

उस वर्ग के लिए जावडोक को देखते हुए यह मुझे हंसता है। उदाहरण के लिए स्पष्ट कुछ भी नहीं – Woot4Moo

+1

@ Woot4Moo आप स्पष्ट रूप से (अनजान पून) समझ में नहीं आता कि यह वर्ग कैसे काम करता है - इसकी कोई क्षमता नहीं है इसलिए इसे साफ़ नहीं किया जा सकता है। –

+3

@ जेड आप स्पष्ट रूप से ऐसा कुछ दस्तावेज करने में विनोद नहीं पाते जो कुछ भी नहीं करता है। – Woot4Moo

3

हम एक असीम लागू कर सकते हैं कंसूरेंट लिंक्ड कतार और एक निष्पक्ष सेमफोर जैसी असंबद्ध कतार का उपयोग करके निष्पक्ष अवरुद्ध कतार। नीचे दी गई कक्षा ब्लॉकिंग क्यूई इंटरफेस से सभी विधियों को लागू नहीं करती है, लेकिन प्रदर्शन उद्देश्यों के लिए उनमें से कुछ ही। मुख्य() विधि केवल एक परीक्षण के रूप में लिखा जाता है।

public class FairBlockingQueue<T> { 

    private final Queue<T> queue; 
    private final Semaphore takeSemaphore; 

    public FairBlockingQueue() { 
     queue = new ConcurrentLinkedQueue<T>(); 
     takeSemaphore = new Semaphore(0, true); 
    } 

    public FairBlockingQueue(Collection<T> c) { 
     queue = new ConcurrentLinkedQueue<T>(c); 
     takeSemaphore = new Semaphore(c.size(), true); 
    } 

    public T poll() { 
     if (!takeSemaphore.tryAcquire()) { 
      return null; 
     } 
     return queue.poll(); 
    } 

    public T poll(long millis) throws InterruptedException { 
     if (!takeSemaphore.tryAcquire(millis, TimeUnit.MILLISECONDS)) { 
      return null; 
     } 
     return queue.poll(); 
    } 

    public T take() throws InterruptedException { 
     takeSemaphore.acquire(); 
     return queue.poll(); 
    } 

    public void add(T t) { 
     queue.add(t); 
     takeSemaphore.release(); 
    } 

    public static void main(String[] args) throws Exception { 
     FairBlockingQueue<Object> q = new FairBlockingQueue<Object>(); 
     Object o = q.poll(); 
     assert o == null; 
     o = q.poll(1000); 
     assert o == null; 

     q.add(new Object()); 
     q.add(new Object()); 
     q.add(new Object()); 

     o = q.take(); 
     assert o != null; 
     o = q.poll(); 
     assert o != null; 
     o = q.poll(1000); 
     assert o != null; 

     o = q.poll(); 
     assert o == null; 
    } 
} 
+0

अच्छा और निष्पक्ष समाधान, हालांकि मैं प्राथमिकताब्लॉकिंग क्यूयू – Michael

+0

धन्यवाद, माइकल का उपयोग करने का सुझाव देता हूं। अगर हम कुछ ऑफ-द-बॉक्स का उपयोग करना चाहते हैं तो हम निश्चित रूप से प्राथमिकताब्लॉकिंग्यूयू के लिए जा सकते हैं, हालांकि पीबीक्यू और ऊपर दिए गए एफबीक्यू का सुझाव सॉर्टिंग/ऑर्डरिंग के संबंध में अलग है। पीबीक्यू अपने तत्वों को प्राथमिकता के ढेर का उपयोग करके अपने प्राकृतिक आदेश के अनुसार आदेश देता है, और पीबीक्यू से तत्वों को लेना इस विशेष क्रम में होता है, जबकि एफबीक्यू को एक समवर्ती लिंक्ड क्यूई द्वारा समर्थित किया जाता है जो एक सामान्य फीफो कतार है। –

+2

बीटीडब्लू, जावा एसई 6 से प्राथमिकताब्लॉकिंग क्यूई में टेक() ले जाने के लिए कॉलर के लिए उचित है क्योंकि इसे एक उचित पुनर्विक्रेता लॉक के साथ लागू किया गया है, लेकिन जावा एसई 7 में इसे गैर-निष्पक्ष पुनर्विक्रय लॉक के साथ कार्यान्वित किया गया है और क्रमशः यह कॉलर्स के लिए उचित नहीं है। अभी स्रोतों की जांच की है। –

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