2012-04-12 14 views
7

मूल रूप से मुझे सर्वर की ओर अस्थायी चैट संदेशों को संग्रहीत करने के लिए डेटा संरचना की आवश्यकता है। यह होना चाहिए:जावा समेकित गैर-अवरुद्ध बफर उच्च समवर्ती स्थिति

  • घिरा: क्योंकि मैं दुकान में बहुत ज्यादा संदेश की जरूरत नहीं है, ग्राहक नए संदेश हर दूसरे पाने के लिए अनुरोध भेज देंगे। मुझे लगता है कि बाध्य आकार अधिकतम होना चाहिए। एक सेकंड में समवर्ती अनुरोधों का माउंट। जब बफर भर जाता है, तो पुराने संदेश हटा दिए जाएंगे।

  • उच्च समवर्ती पहुंच के लिए उपयुक्त: मैं संग्रह संरचनाओं जैसे डेटा संरचना का उपयोग नहीं करना चाहता, क्योंकि पुनरावृत्ति के दौरान, यदि अन्य थ्रेड डेटा संरचना को बदलता है, उदा। एक संदेश जोड़ता है, यह एक अपवाद फेंक देगा, इसलिए मुझे पूरी डेटा संरचना को लॉक करना होगा, वास्तव में मुझे वास्तव में परवाह नहीं है कि क्लाइंट अनुरोध सबसे आखिरी डाला गया संदेश प्राप्त कर सकता है, क्योंकि वे एक सेकंड के बाद एक नया अनुरोध भेजेंगे, दूसरी तरफ लेखन ऑपरेशन कभी देरी नहीं होनी चाहिए। पैकेज java.util.concurrency के तहत कक्षाएं समाधान लगता है, लेकिन ...

  • गैर-अवरुद्ध: लिंक्डब्लॉकिंग क्यूयू, ऐरेब्लॉकिंग क्यूईयू उन्हें बाध्य किया जा सकता है और पुनरावृत्ति के दौरान अपवाद नहीं फेंक देगा, लेकिन वे सभी अवरुद्ध कतार हैं। जब कतार भर जाती है, तो मैं पूंछ में नया तत्व जोड़ना चाहता हूं और वहां से अवरुद्ध करने के बजाय पुराने तत्व को सिर से हटा देना चाहता हूं और किसी के लिए हेडर को हटाने का इंतजार करना चाहता हूं।

तो मेरा प्रश्न तीसरी लाइब्रेरी से कोई अच्छा कार्यान्वयन है? उदाहरण के लिए Google गुवा? या शायद आपके पास सर्वर पर अस्थायी चैट संदेश संग्रहीत करने के बारे में बेहतर विचार है?

आपको बहुत बहुत धन्यवाद!

+3

आप अपाचे कॉमन्स [CircularFifoBuffer] (http://commons.apache.org/collections/apidocs/org/apache/commons/collections/buffer/CircularFifoBuffer.html) की एक सिंक्रनाइज़ संस्करण की कोशिश कर सकते। – Perception

+0

आपके उत्तर के लिए धन्यवाद, वास्तव में परिपत्रफिफ़ोफर बिल्कुल वही है जो मुझे चाहिए। लेकिन यह बॉक्स से सिंक्रनाइज़ नहीं है, क्योंकि इसके दस्तावेज़ से पता चलता है, मुझे चाहिए: BufferUtils.synchronizedBuffer (नया परिपत्रफिफो बफर()); लेकिन मैंने BufferUtils के स्रोत कोड की जांच की, यह सिर्फ जेआरई संग्रह। सिंक्रनाइज़ XXXXX की तरह, प्रत्येक सार्वजनिक कार्यों में सिंक्रनाइज़ किए गए कीवर्ड को जोड़ता है, इस मामले में प्रदर्शन समस्याएं समान होती हैं। – cn1h

+0

वैसे भी मुझे नहीं लगता कि बफर की क्षमता बहुत बड़ी होनी चाहिए। इसलिए यदि मैं पढ़ने के दौरान पूरी डेटा संरचना को लॉक करता हूं, तो यह भी एक बड़ी समस्या नहीं होनी चाहिए। मुझे लगता है कि आपका जवाब सही जवाब है, लेकिन मुझे नहीं पता कि इसे कैसे स्वीकार किया जाए। – cn1h

उत्तर

4

आप अपाचे कॉमन्स CircularFifoBuffer का उपयोग कर सकते हैं। यह आपके पहले और अंतिम मानदंडों को पूरा करता है।परियोजना पर

Buffer fifo = BufferUtils.synchronizedBuffer(new CircularFifoBuffer()); 

गुड लक: संगामिति समर्थन करने के लिए, आप लपेट कर सकते हैं उस में आधार बफर तो जैसे संस्करण सिंक्रनाइज़ होती है।

2

क्या आपने ConcurrentLinkedQueue पर एक नज़र डाली? पेज का कहना है

इस कार्यान्वयन के लिए एक कुशल "प्रतीक्षा मुक्त" एल्गोरिथ्म को रोजगार ...

प्रतीक्षा-स्वतंत्रता सबसे मजबूत गारंटी आप प्राप्त कर सकते हैं में से एक है ....

+1

ConcurrentLinkedQueue बाध्य नहीं है। हालांकि इसे आकार व्यवहार जोड़ने के लिए लपेटा/उप-वर्गीकृत किया जा सकता है। –

+1

मैंने फिर से पढ़ा और आप सही हैं। असंबद्ध प्रतीक्षा मुक्त? पता नहीं था कि ऐसी चीज मौजूद थी। उन्हें डॉक्टर को सही करना चाहिए क्योंकि यह – UmNyobe

+0

को मेरी पिछली टिप्पणी को नजरअंदाज नहीं करता है। मुझे कतार के आकार में बाध्य किया गया था, जिसमें परिचालन के समय में सीमा थी। – UmNyobe

-2

ConcurrentLinkedQueue विस्तार, आप का उपयोग कर सकते हैं:

private int capacity; 

// proper constructor 

public boolean add(E e) { 
    synchronized(mutex) { 
    if (super.size() == capacity) { 
     super.remove(super.element()); 
    } 
    } 
    return super.add(e); 
} 

बहरहाल, यहके लिए कॉल करने के लिए एक ओवरहेड डालता हैविधि। उच्च आवृत्ति आवश्यकता पर, add(E e) जैसी विधियों को ओवरराइड करना बेहतर होता है।

टिप्पणी पर आधारित अद्यतन।

+2

न केवल 'आकार()' विधि पर कॉल पर ओवरहेड डालता है, लेकिन यह ऐसी विधि के अंदर तत्वों को निकालने के लिए अजीब लगता है। जैसा कि आपने बताया है, तत्वों को जोड़े जाने पर मैं इसे करूँगा। –

+0

यह समाधान आकार के रूप में उड़ाता है ओ (1) और यह क्रोध है। यह काम नहीं करेगा। – bestsss

+0

गलती: आकार * नहीं * ओ (1) – bestsss

0

LinkedTransferQueue एक अवरुद्ध, असंबद्ध कतार है जो सख्त फीफो ऑर्डरिंग लागू नहीं करती है। यह खाली कतार से लेने पर ही अवरुद्ध होगा, लेकिन कभी भी एक को जोड़ने पर नहीं। आप या तो आकार जोड़कर तत्वों को बेदखल करने के लिए नरम टोपी जोड़ सकते हैं या & लिखने वाले काउंटर पढ़ सकते हैं।

आपकी आवश्यकताओं के आधार पर, आप कस्टम लॉक-फ्री रिंग बफर लिखने में सक्षम हो सकते हैं।

+0

ट्रांसफरक्यूयू ठंडा है लेकिन अभी भी अनबाउंड है और अनबाउंड लोग बुरी तरह चूसते हैं क्योंकि कुछ भी नहीं होने पर कोई बात नहीं है। – bestsss

1

आप एक सशर्त offer() बयान है, जहां कतार सिर में प्रस्ताव परिणाम को स्वीकार करने की विफलता गिरा दिया जा रहा है और प्रस्ताव के साथ आसपास के द्वारा एक ArrayBlockingQueue करने के लिए गैर अवरुद्ध व्यवहार जोड़ सकते हैं फिर से बनाया जा रहा है:

public class LearnToQueue { 


    public static void main(String[] args){ 
     Queue<Integer> FIFO = new ArrayBlockingQueue<Integer>(4); 

     int i = 0; 

     while (i < 10){ 

      if (!FIFO.offer(i)){ 
      // You can pipe the head of the queue anywhere you want to 
       FIFO.remove(); 
       FIFO.offer(i); 
      } 
      System.out.println(FIFO.toString()); 
      i++; 

     } 
    } 

    } 
4

आप LinkedBlockingQueue का उपयोग गैर-अवरुद्ध विधियों offer (या add) और poll के साथ पहुंचने के लिए कर सकते हैं। आप इसे बाध्य करने के लिए एक निश्चित क्षमता के साथ बना सकते हैं।

LinkedBlockingQueue<String> myStrings = new LinkedBlockingQueue<String>(100); 
myStrings.offer("Hi!"); // returns false if limit is reached 
myStrings.add("Hi, again!"); // throws exception if limit is reached 
String s = myStrings.poll(); // returns null if queue is empty 
+0

'लिंक्डब्लॉकिंग क्यूयू' एक लॉक प्राप्त करता है यदि कतार 'ऑफर' पर कॉल करने पर भी पूर्ण नहीं है, तो यह मुफ्त में प्रतीक्षा नहीं है। –

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