हाल ही में एक ऐसे प्रोजेक्ट पर काम करने के लिए जिसकी मुझे आवश्यकता है, उससे कुछ और आईओ इंटरैक्शन की आवश्यकता है, मुझे लगा जैसे मैं नियमित पुस्तकालयों (विशेष रूप से कॉमन्स आईओ) को देखना चाहता था और कुछ और से निपटना चाहता था गहराई आईओ मुद्दों।जावा मल्टीथ्रेडेड फ़ाइल डाउनलोड प्रदर्शन
अकादमिक परीक्षण के रूप में, मैंने एक बुनियादी, बहु-थ्रेडेड HTTP डाउनलोडर को लागू करने का निर्णय लिया। विचार सरल है: डाउनलोड करने के लिए एक यूआरएल प्रदान करें, और कोड फ़ाइल डाउनलोड करेगा। डाउनलोड गति को बढ़ाने के लिए, फ़ाइल को खंडित किया गया है और जितना संभव हो उतना बैंडविड्थ का उपयोग करने के लिए प्रत्येक खंड एक साथ डाउनलोड किया जाता है (HTTP Range: bytes=x-x
शीर्षलेख का उपयोग करके)।
मेरे पास एक कामकाजी प्रोटोटाइप है, लेकिन जैसा कि आपने अनुमान लगाया होगा, यह बिल्कुल आदर्श नहीं है। फिलहाल मैं मैन्युअल रूप से 3 "डाउनलोडर" धागे शुरू करता हूं जो प्रत्येक फ़ाइल के 1/3 डाउनलोड करते हैं। ये धागे वास्तव में डिस्क पर फ़ाइलों को लिखने के लिए एक सामान्य, सिंक्रनाइज़ "फ़ाइल लेखक" उदाहरण का उपयोग करते हैं। जब सभी धागे किए जाते हैं, तो "फ़ाइल लेखक" पूरा हो जाता है और कोई भी खुली धाराएं बंद होती हैं। कोड में से कुछ के टुकड़े आप यह अनुमान लगा रहे हैं:
धागा शुरू हुआ:
ExecutorService downloadExecutor = Executors.newFixedThreadPool(3);
...
downloadExecutor.execute(new Downloader(fileWriter, download, start1, end1));
downloadExecutor.execute(new Downloader(fileWriter, download, start2, end2));
downloadExecutor.execute(new Downloader(fileWriter, download, start3, end3));
प्रत्येक "डाउनलोडर" धागा एक हिस्सा (बफ़र) डाउनलोड करता है और डिस्क पर लिखने के लिए "फ़ाइल लेखक" का उपयोग करता है:
public synchronized void write(byte[] bytes, int len, long start) throws IOException
{
output.seek(start);
output.write(bytes, 0, len);
}
:
int bytesRead = 0;
byte[] buffer = new byte[1024*1024];
InputStream inStream = entity.getContent();
long seekOffset = chunkStart;
while ((bytesRead = inStream.read(buffer)) != -1)
{
fileWriter.write(buffer, bytesRead, seekOffset);
seekOffset += bytesRead;
}
"फ़ाइल लेखक" एक RandomAccessFile
seek()
करने और write()
डिस्क के लिए मात्रा का उपयोग कर डिस्क के लिए लिखता है
सभी चीजों को माना जाता है, यह दृष्टिकोण काम करने लगता है। हालांकि, यह बहुत अच्छी तरह से काम नहीं करता है। मैं निम्नलिखित बिंदुओं पर कुछ सलाह/सहायता/राय की सराहना करता हूं। बहुत सराहना की।
- इस कोड का CPU उपयोग छत के माध्यम से है। यह ऐसा करने के लिए आधे मेरे सीपीयू (2 कोरों में से प्रत्येक का 50%) का उपयोग कर रहा है, जो तुलनीय डाउनलोड टूल्स की तुलना में तेजी से अधिक है जो सीपीयू को मुश्किल से तनाव देता है। मैं थोड़ा सा रहस्यमय हूं कि यह सीपीयू उपयोग कहां से आता है, क्योंकि मुझे इसकी उम्मीद नहीं थी।
- आमतौर पर, 312 धागे में से 1 प्रतीत होता है जो के पीछे महत्वपूर्ण है। अन्य 2 धागे खत्म हो जाएंगे, जिसके बाद यह तीसरा धागा लेता है (जो कि पहले खंड के साथ सबसे पहले धागा लगता है) पूरा करने के लिए 30 या अधिक सेकंड। मैं टास्क मैनेजर से देख सकता हूं कि जाव प्रक्रिया अभी भी छोटे आईओ लिख रही है, लेकिन मुझे नहीं पता कि यह क्यों होता है (मैं दौड़ की स्थिति का अनुमान लगा रहा हूं?)।
- इस तथ्य के बावजूद कि मैंने काफी बड़ा बफर (1 एमबी) चुना है, मुझे लगता है कि
InputStream
लगभग वास्तव में कभी भी बफर भरता नहीं है, जो मुझे पसंद होने से अधिक आईओ लिखता है। मैं इस धारणा के तहत हूं कि इस परिदृश्य में, आईओ पहुंच को न्यूनतम रखने के लिए सबसे अच्छा होगा, लेकिन मुझे यह सुनिश्चित नहीं है कि यह सबसे अच्छा तरीका है या नहीं। - मुझे एहसास है कि जावा ऐसा कुछ करने के लिए आदर्श भाषा नहीं हो सकता है, लेकिन मुझे पूरा विश्वास है कि मेरे वर्तमान कार्यान्वयन में मुझे जितना अधिक प्रदर्शन करना है। एनआईओ इस मामले में तलाश लायक है?
नोट: मैं है कि कौन सी HTTP बातचीत करने के लिए, Apache httpclient का उपयोग जहां entity.getContent()
से (मामले में किसी को भी सोच रहा है) आता है।
मिले यहाँ एक अच्छा संबंधित विषय: http://stackoverflow.com/questions/921262/how-to-download-and-save-a-file-from-internet-using-java दे सकता है कि आज रात आज़माएं जब मैं घर जाऊं :) – tmbrggmn
अद्यतन: उच्च CPU उपयोग निष्पादक सेवा पर थोड़ी देर() लूप के कारण था (निर्धारित विधि)। रवींद्र! – tmbrggmn
मुझे लगता है कि नेटवर्क कॉन्फ़िगरेशन पर भी निर्भर करता है, और नेटवर्क इंटरफेस कार्ड (भौतिक)। भले ही आपके पास एक ही फ़ाइल को डाउनलोड करने पर काम करने वाले कई धागे हैं लेकिन एनआईसी, जो बाइट्स को क्रमबद्ध करने के लिए ज़िम्मेदार है, बाधा बन सकती है !! – TriCore