AsyncTask doInBackground () से सामान चलाने के लिए एक थ्रेड पूल पैटर्न का उपयोग करता है। मुद्दा शुरू में (शुरुआती एंड्रॉइड ओएस संस्करणों में) पूल का आकार सिर्फ 1 था, जिसका अर्थ है AsyncTasks के एक गुच्छा के लिए कोई समानांतर गणना नहीं। लेकिन बाद में उन्होंने तय किया कि और अब आकार 5 है, इसलिए अधिकतम 5 AsyncTasks एक साथ चल सकते हैं। दुर्भाग्य से मुझे याद नहीं है कि वास्तव में उन्होंने किस संस्करण में बदलाव किया है।
अपडेट करें:
इस पर वर्तमान (2012-01-27) एपीआई क्या कहता है:
जब पहली बार पेश किया गया, तो AsyncTasks को एकल पृष्ठभूमि थ्रेड पर क्रमिक रूप से निष्पादित किया गया था। डोनट के साथ शुरू करके, इसे थ्रेड्स के एक पूल में बदल दिया गया, जिससे कई कार्यों को समानांतर में संचालित किया जा सके। हनीकॉम के बाद, समानांतर निष्पादन के कारण होने वाली सामान्य अनुप्रयोग त्रुटियों से बचने के लिए इसे वापस एक सूत्र में बदलने की योजना है। यदि आप वास्तव में समानांतर निष्पादन चाहते हैं, तो आप THREAD_POOL_EXECUTOR के साथ इस विधि के निष्पादन योग्य (निष्पादनकर्ता, परम ...) संस्करण का उपयोग कर सकते हैं; हालाँकि, इसके उपयोग पर चेतावनी के लिए कमेंट्री देखें।
डोनट एंड्रॉइड 1.6 है, हनीकॉम एंड्रॉइड 3.0 है।
अद्यतन: 2
द्वारा टिप्पणी देखें kabuko
से Mar 7 2012 at 1:27
।
यह पता चलता है कि एपीआई के लिए जहां "समानांतर में कई कार्यों को संचालित करने की अनुमति देने वाले थ्रेड्स का एक पूल" का उपयोग किया जाता है (1.6 से शुरू और 3.0 पर समाप्त होता है) साथ-साथ चलने वाले एसिंक्सटैक्सेस की संख्या इस बात पर निर्भर करती है कि पहले से ही निष्पादन के लिए कितने कार्य पारित किए गए हैं, लेकिन doInBackground()
अभी तक उनका अंत नहीं किया है।
यह मेरे द्वारा 2.2 पर परीक्षण / पुष्टि की गई है। मान लीजिए कि आपके पास एक कस्टम AsyncTask है जो सिर्फ एक सेकंड में सोता है doInBackground()
। AsyncTasks विलंबित कार्यों के भंडारण के लिए आंतरिक रूप से एक निश्चित आकार की कतार का उपयोग करता है। कतार का आकार डिफ़ॉल्ट रूप से 10 है। यदि आप एक पंक्ति में 15 अपने कस्टम कार्य शुरू करते हैं, तो पहले 5 उनके प्रवेश करेंगे doInBackground()
, लेकिन बाकी एक मुक्त कर्मचारी थ्रेड के लिए एक कतार में इंतजार करेंगे। जैसे ही पहले 5 में से कोई भी खत्म होता है, और इस तरह एक श्रमिक धागा जारी होता है, कतार से एक कार्य निष्पादन शुरू हो जाएगा। तो इस मामले में अधिकतम 5 कार्य एक साथ चलेंगे। हालाँकि, यदि आप एक पंक्ति में 16 अपने कस्टम कार्य शुरू करते हैं, तो पहले 5 उनके प्रवेश करेंगे doInBackground()
, बाकी 10 कतार में लग जाएंगे, लेकिन 16 वें के लिए एक नया वर्कर थ्रेड बनाया जाएगा ताकि यह तुरंत निष्पादन शुरू कर देगा। तो इस मामले में अधिकतम 6 कार्य एक साथ चलेंगे।
एक साथ कितने कार्यों को चलाया जा सकता है, इसकी एक सीमा है। चूँकि AsyncTask
थ्रेड पूल निष्पादक का उपयोग सीमित संख्या में वर्कर थ्रेड्स (128) के साथ होता है और विलंबित कार्य कतार का आकार 10 है, यदि आप 138 से अधिक को निष्पादित करने का प्रयास करते हैं तो ऐप आपके साथ क्रैश हो जाएगा java.util.concurrent.RejectedExecutionException
।
3.0 से शुरू होकर एपीआई आपके कस्टम थ्रेड पूल एक्ज़ीक्यूटर को AsyncTask.executeOnExecutor(Executor exec, Params... params)
विधि के माध्यम से उपयोग करने की अनुमति देता है । यह अनुमति देता है, उदाहरण के लिए, विलंबित कार्य कतार के आकार को कॉन्फ़िगर करने के लिए यदि डिफ़ॉल्ट 10 वह नहीं है जो आपको चाहिए।
@Knossos का उल्लेख है, AsyncTaskCompat.executeParallel(task, params);
एपीआई स्तर के साथ परेशान किए बिना समानांतर में कार्यों को चलाने के लिए समर्थन v.4 पुस्तकालय से उपयोग करने का एक विकल्प है। यह विधि एपीआई स्तर 26.0.0 में पदावनत हो गई।
अद्यतन: 3
कार्यों की संख्या, सीरियल बनाम समानांतर निष्पादन के साथ खेलने के लिए यहां एक सरल परीक्षण ऐप है: https://github.com/vitkhudenko/test_asynctask
अद्यतन: 4 (यह इंगित करने के लिए धन्यवाद @penkzhou)
एंड्रॉइड 4.4 से शुरू AsyncTask
करना UPDATE: 2 अनुभाग में वर्णित अलग-अलग व्यवहार करता है । वहाँ एक ठीक है को रोकने के लिए AsyncTask
भी कई धागे बनाने से।
Android 4.4 (API 19) से AsyncTask
पहले निम्नलिखित क्षेत्र थे:
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(10);
एंड्रॉइड 4.4 (एपीआई 19) में उपरोक्त फ़ील्ड इसे बदल दिए गए हैं:
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(128);
यह परिवर्तन कतार के आकार को 128 आइटम तक बढ़ाता है और CPU कोर की संख्या के लिए थ्रेड्स की अधिकतम संख्या को कम करता है * 2 + 1. ऐप्स अभी भी समान संख्या में कार्य सबमिट कर सकते हैं।