2013-04-23 5 views
5

पर पढ़ता है अब थोड़ी देर के लिए देख रहा था और मैं इस मुद्दे पर थोड़ा उलझन में हूं। मैं एक इनपुट स्ट्रीम लेने में सक्षम होना चाहता हूं और इसे सेगमेंट में समवर्ती रूप से पढ़ना चाहता हूं। सेगमेंट एक दूसरे के साथ बातचीत नहीं करते हैं, वे केवल अपलोड किए गए फ़ाइल से डेटाबेस में डालने या अपडेट करने के लिए मूल्य हैं। क्या एक सेगमेंट आकार सेट करके समवर्ती रूप से एक इनपुट स्ट्रीम पढ़ना संभव है और फिर रूपांतरण को सम्मिलित करने और अपडेट/अपडेट करने के लिए एक नए थ्रेड को कताई करने से पहले बस छोड़ना संभव है?जावा: समवर्ती एक इनपुटस्ट्रीम

अनिवार्य रूप से फ़ाइल आईडी की एक सूची (प्रति पंक्ति एक आईडी) है, हालांकि अगर मैं एक विभाजक निर्दिष्ट कर सकता हूं तो यह बेहतर होगा। कुछ फाइलें बड़ी हो सकती हैं इसलिए मैं डेटा को सेगमेंट में संसाधित और कनवर्ट करना चाहता हूं ताकि डेटाबेस में डालने/अपडेट करने के बाद JVM मेमोरी को मुक्त किया जा सके। क्या यह संभव है? और यदि ऐसा है तो वहां कोई पुस्तकालय है जो पहले से ही ऐसा करता है?

चीयर्स और अग्रिम धन्यवाद,

एलेक्सी ब्लू।

उत्तर

6

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

नीचे एक उदाहरण है जो प्रत्येक पंक्ति की प्रसंस्करण को System.in से कार्यकर्ता धागे में बंद कर देता है। डेटाबेस प्रविष्टियों का प्रदर्शन बहुत बेहतर होता है यदि आप एक ही लेनदेन के भीतर बड़ी संख्या में आवेषण करते हैं तो उदाहरण के अनुसार एक पंक्ति में गुजरने से 1000 पंक्तियों के समूह में गुजरना बेहतर होगा।

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class Main { 
    public static class Worker implements Runnable { 
     private final String line; 

     public Worker(String line) { 
      this.line = line; 
     } 

     @Override 
     public void run() { 
      // Process line here. 
      System.out.println("Processing line: " + line); 
     } 
    } 

    public static void main(String[] args) throws IOException { 
     // Create worker thread pool. 
     ExecutorService service = Executors.newFixedThreadPool(4); 

     BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in)); 
     String line; 

     // Read each line and hand it off to a worker thread for processing. 
     while ((line = buffer.readLine()) != null) { 
      service.execute(new Worker(line)); 
     } 
    } 
} 
+0

हाय एड उदाहरण के लिए धन्यवाद ^।^इसलिए यदि मैं स्ट्रिंगबफर में 1000 लाइनें पढ़ता हूं और फिर इसे एक वर्कर थ्रेड पर पास करता हूं जिसे संसाधित और डेटाबेस में डाला/अपडेट किया जाता है, तो क्या आपको लगता है कि यह एक अच्छा दृष्टिकोण होगा? :) –

+0

शायद 'लाइन ' या 'स्ट्रिंग [] 'में 1000 लाइनों को पढ़ने के लिए सबसे अच्छा होगा। यदि आप उन्हें 'स्ट्रिंगबफर' में पढ़ते हैं तो यह एक स्ट्रिंग होगी और आपको दूसरी बार अलग-अलग लाइनों को पार्स करना होगा। –

1

मुझे नहीं लगता कि आप एक इनपुटस्ट्रीम को समवर्ती रूप से पढ़ सकते हैं। यही कारण है कि अनुबंध पढ़ने, रीसेट करने और चिह्नित करने के लिए परिभाषित करता है - विचार यह है कि स्ट्रीम आंतरिक रूप से ट्रैक करता है जो पढ़ा गया है और क्या नहीं है।

यदि आप कोई फ़ाइल पढ़ रहे हैं, तो बस कई स्ट्रीम खोलें। डुप्लिकेट लाइन प्रोसेसिंग से बचने के लिए आप अन्य थ्रेड के लिए मार्कर को आगे बढ़ाने के लिए skip() विधि का उपयोग कर सकते हैं। BufferedReader कुछ भी मदद कर सकता है, क्योंकि यह line by line पढ़ने की पेशकश करता है।

+0

हाँ बफर्ड रीडर + स्किप जिस तरह से मैं वर्तमान में कर रहा हूं, मुझे थोड़ा और काम करने की ज़रूरत है, लेकिन मुझे यकीन है कि एक सिंगल अनुक्रमिक पढ़ने और अन्य धागे पर चलने वाले काम का उपयोग करना एक अच्छा सुधार होगा। लिंक के लिए चीयर्स। –

1

सबसे पहले, फ़ाइल को अलग-अलग ऑफसेट से शुरू करने के लिए फ़ाइल को पढ़ने के लिए आपको फ़ाइल में यादृच्छिक पहुंच की आवश्यकता है, इसका मतलब किसी भी स्थिति से फ़ाइल पढ़ना है। जावा java.nio में java.in में या SeekableByteChannel साथ RandomAccessFile के साथ इस अनुमति देता है:

Best Way to Write Bytes in the Middle of a File in Java

http://docs.oracle.com/javase/tutorial/essential/io/rafs.html

मैं गति कारणों से आप java.nio चुनाव करेगा, के लिए लगता है। Java NIO FileChannel versus FileOutputstream performance/usefulness

अब आप जानते हैं कि किसी भी स्थिति से कैसे पढ़ा जाए लेकिन आपको इसे एक साथ करने की आवश्यकता है। एक ही फ़ाइल एक्सेस ऑब्जेक्ट के साथ यह संभव नहीं है क्योंकि वे फ़ाइल में स्थिति रखते हैं। इस प्रकार आपको थ्रेड के रूप में कई फ़ाइल एक्सेस ऑब्जेक्ट्स की आवश्यकता होती है। चूंकि आप लिखना नहीं पढ़ रहे हैं जो ठीक होना चाहिए।

अब आप जानते हैं कि एक ही फाइल को कई अलग-अलग ऑफ़सेट से कैसे पढ़ा जाए।

लेकिन प्रदर्शन के बारे में सोचें।धागे की संख्या के बावजूद आपके पास केवल एक डिस्क ड्राइव है और यादृच्छिक पढ़ता है (कई धागे एक ही फ़ाइल तक पहुंचते हैं) प्रदर्शन बहुत धीमा है तो अनुक्रमिक पढ़ता है (एक थ्रेड एक फ़ाइल पढ़ता है)। भले ही यह RAID 0 या 1 है - इससे कोई फर्क नहीं पड़ता। अनुक्रमिक पढ़ने हमेशा बहुत तेज है। तो आपके मामले में मैं आपको एक थ्रेड में फ़ाइल को पढ़ने और उस थ्रेड से डेटा के साथ अन्य धागे की आपूर्ति करने की सलाह दूंगा।

+0

चीयर्स विटाली और लिंक के लिए धन्यवाद –

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