2012-06-07 16 views
5

मेरे पास एक बहु थ्रेडेड एप्लिकेशन है जिसमें एक निर्माता थ्रेड और कई उपभोक्ता धागे हैं। डेटा को साझा थ्रेड सुरक्षित संग्रह में संग्रहीत किया जाता है और बफर में पर्याप्त डेटा होने पर डेटाबेस में फ़्लश किया जाता है।मल्टीथ्रेडेड जावा एप्लिकेशन में डेटा बफरिंग

javadocs से

-

BlockingQueue<E> 

एक कतार है कि इसके साथ ही आपरेशन जब एक तत्व को पुन: प्राप्त कतार गैर खाली बनने के लिए, और अंतरिक्ष के लिए प्रतीक्षा कतार में उपलब्ध होने के लिए जब एक तत्व भंडारण इंतजार है कि समर्थन करता है ।

take() 

इस कतार के सिर को पुनर्प्राप्त और हटा देता है, जब तक कोई तत्व उपलब्ध न हो जाए, तब तक आवश्यक हो।

मेरे सवालों -

  1. एक और संग्रह एक ई [] ले (पूर्णांक एन) विधि है कि है? यानी अवरुद्ध कतार एक तत्व उपलब्ध होने तक प्रतीक्षा करता है। मैं क्या चाहता हूं है कि इसे 100 या 200 तत्व उपलब्ध होने तक प्रतीक्षा करनी चाहिए।
  2. वैकल्पिक रूप से, क्या कोई और तरीका है जिसका उपयोग मैं मतदान के बिना समस्या का समाधान करने के लिए कर सकता हूं?
+0

तत्वों प्रत्येक उपभोक्ता के लिए समान रूप से वितरित किया जाना चाहिए, या विधि ले करने के लिए पहले उपभोक्ता पहले 'n' तत्वों, दूसरा उपभोक्ता अगले' n' तत्वों, आदि मिलना चाहिए? – SimonC

+0

क्या यह वाकई आप क्या करना चाहते हैं?यह उत्पादित होने के बीच लगभग मनमाने ढंग से बड़ी विलंबता पेश कर सकता है और डेटाबेस में फ़्लश किया जा रहा है यदि उत्पादन की दर कभी भी आपके द्वारा ट्यूनिंग समाप्त होने से परे धीमी हो जाती है। यदि आपको वास्तव में अपने सभी तर्कों पर इस बफरिंग को करने की ज़रूरत है तो शायद "जैसे ही मेरे पास एन तत्व हैं या एक्स एम पास हो गए हैं" की प्रतीक्षा करें " – DRMacIver

+0

आप क्यों इंतजार करना चाहते हैं? क्यों न केवल 'नाली() 'का उपयोग करें? मैं आपके द्वारा उपलब्ध अधिकतम डेटा को अधिकतम कुछ लिखूंगा और मैं डेटा खोना नहीं चाहूंगा। –

उत्तर

2

मुझे लगता है कि एक ही रास्ता है या तो BlockingQueue के कुछ कार्यान्वयन को बढ़ाने या take का उपयोग करके किसी प्रकार की उपयोगिता विधि बनाएं:

public <E> void take(BlockingQueue<E> queue, List<E> to, int max) 
     throws InterruptedException { 

    for (int i = 0; i < max; i++) 
     to.add(queue.take()); 
} 
+0

दरअसल, आपका दृष्टिकोण मेरे मुकाबले ज्यादा स्वच्छ है, यह मानते हुए कि केवल एक उपभोक्ता होने वाला है। – Zarkonnen

+1

यह दृष्टिकोण इंटरप्टेडएक्सप्शन के साथ बिल्कुल भी सौदा नहीं करता है क्योंकि यदि आप बाधित होते हैं तो आप किसी भी तत्व को खो देते हैं। इसे वास्तव में संग्रह में पारित करने के लिए तत्वों को जोड़ने की आवश्यकता है यदि यह स्वयं को बाधित करने के लिए नहीं जा रहा है, या अब तक निकाले गए तत्वों को पकड़ने और वापस करने के लिए। – DRMacIver

+0

ओह, टिप्पणी पर अच्छा बिंदु +1। अपडेट किया गया! – dacwe

1

मैं नहीं यकीन है कि तुम वहाँ मानक पुस्तकालय है कि take(int n) प्रकार विधि में एक समान वर्ग अगर हूँ, लेकिन आप बहुत ज्यादा परेशानी के बिना है कि समारोह में जोड़ने के लिए डिफ़ॉल्ट BlockingQueue रैप करने के लिए सक्षम होना चाहिए, क्या नहीं सोच?

वैकल्पिक परिदृश्य एक क्रिया को ट्रिगर करना होगा जहां आप संग्रह में तत्व डालते हैं, जहां आपके द्वारा निर्धारित थ्रेसहोल्ड फ्लशिंग को ट्रिगर करेगा।

2

drainTo विधि बिल्कुल वही नहीं है जो आप खोज रहे हैं, लेकिन क्या यह आपके उद्देश्य की सेवा करेगा?

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html#drainTo(java.util.Collection, पूर्णांक)

संपादित

आप take और drainTo के संयोजन का उपयोग takemin अवरुद्ध एक से थोड़ा अधिक performant बैच को लागू कर सकते हैं:

public <E> void drainTo(final BlockingQueue<E> queue, final List<E> list, final int min) throws InterruptedException 
{ 
    int drained = 0; 
    do 
    { 
    if (queue.size() > 0) 
     drained += queue.drainTo(list, min - drained); 
    else 
    { 
     list.add(queue.take()); 
     drained++; 
    } 
    } 
    while (drained < min); 
} 
+1

की निश्चित दर के साथ एक रासायनिक सेंसर है। यह वह है जो वह करना चाहता है। – posdef

+0

मैंने यह इंगित करने के लिए उत्तर अपडेट किया है कि यह सटीक प्रश्न हल नहीं करता है। कभी-कभी ओपी वैकल्पिक समाधानों से अवगत नहीं है, इसलिए यह हमेशा पूछने लायक है। – SimonC

+0

इसके खिलाफ बहस करें :) – posdef

1

तो यह एक थ्रेडसेफ कतार होना चाहिए जो आपको तत्वों की मनमाना संख्या लेने पर रोक देगा। थ्रेडिंग कोड को सत्यापित करने के लिए और अधिक आंखों का स्वागत किया जाएगा।

package mybq; 

import java.util.ArrayList; 
import java.util.LinkedList; 
import java.util.List; 

public class ChunkyBlockingQueue<T> { 
    protected final LinkedList<T> q = new LinkedList<T>(); 
    protected final Object lock = new Object(); 

    public void add(T t) { 
     synchronized (lock) { 
      q.add(t); 
      lock.notifyAll(); 
     } 
    } 

    public List<T> take(int numElements) { 
     synchronized (lock) { 
      while (q.size() < numElements) { 
       try { 
        lock.wait(); 
       } catch (InterruptedException e) { 
        Thread.currentThread().interrupt(); 
       } 
      } 
      ArrayList<T> l = new ArrayList<T>(numElements); 
      l.addAll(q.subList(0, numElements)); 
      q.subList(0, numElements).clear(); 
      return l; 
     } 
    } 
} 
+1

'add' में' notifyAll' यहां थोड़ा अपमानजनक है। यह एक 'अधिसूचित' होना चाहिए, फिर 'टेक' फिर से 'अधिसूचित' कॉल कर सकता है यदि ऐसा होने पर अभी भी अधिक तत्व शेष हैं। – SimonC

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