AsyncTask धागे कभी नहीं मरते


112

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

नतीजा बड़ी संख्या में AsyncTaskधागे वहां बैठे हैं। मुझे यकीन नहीं है कि यह अभ्यास में समस्या है या नहीं, लेकिन मैं वास्तव में उन अतिरिक्त थ्रेड्स से छुटकारा पाना चाहूंगा।

मैं इन धागों को कैसे मार सकता हूँ?


"कभी समाप्त नहीं" के साथ आपका क्या मतलब है? क्या कार्य कभी अपने doInbackground पद्धति को समाप्त नहीं करता है या क्या आपको आवंटन आरेख में एसिंक्टस्क ऑब्जेक्ट दिखाई देता है?
फ्रांसेस्को लॉरिटा

7
doInBackgroundविधि को पूरा करता है, लेकिन धागा डिबग खिड़की में दिखाने के लिए जारी है। उदाहरण के लिए: Thread [<23> AsyncTask #4](Running)
कंप्यूटर

जवाबों:


202

AsyncTask एक थ्रेड पूल का प्रबंधन करता है, जिसके साथ बनाया गया है ThreadPoolExecutor । इसमें 5 से 128 तक धागे होंगे। यदि 5 से अधिक धागे हैं, तो वे अतिरिक्त धागे हटाए जाने से पहले लगभग 10 सेकंड के लिए चारों ओर चिपक जाएंगे। (नोट: ये आंकड़े वर्तमान में दिखाई देने वाले खुले स्रोत कोड के लिए हैं और Android रिलीज़ के अनुसार भिन्न हैं)।

AsyncTaskथ्रेड्स को अकेला छोड़ दें , कृपया।


स्पष्टीकरण के लिए धन्यवाद! मुझे यह जानकर खुशी हुई कि मैं कुछ गलत नहीं कर रहा हूं। जिज्ञासा से बाहर, इसे इस तरह क्यों बनाया गया है? सभी विधियों के वापस आने के बाद थ्रेड्स को समाप्त क्यों नहीं किया जाता है?
कम्प्यूटरिश

7
संभवतः बाद के अनुरोधों पर थ्रेड्स के लिए समय बचाने के लिए।
कॉमन्सवेयर

@CommonsWare मेरे पास एक ऐसी सेवा है जिसमें मैं कुछ ऑपरेशन करने के लिए एक AsyncTask चला रहा हूं और सेवा तब शुरू होती है जब विजेट बटन दबाया जा रहा है और जब कार्य समाप्त हो जाता है तो उसे तुरंत सर्विस बंद कर देना चाहिए, लेकिन कभी-कभी AsyncTask बंद नहीं होता है, तो आप यू कर सकते हैं मुझे बताओ कि मैं इसे कैसे
हंट

1
@ श्रीकांतकर्मनघाट: एक AsyncTaskऐसी चीज का उपयोग करना जो सामान्य रूप से एक बुरा विचार है। लेकिन नहीं, अतिरिक्त थ्रेड्स के बारे में मेरी टिप्पणी तब होती है जब वे अप्रयुक्त होते हैं। इसलिए, जब आपका 6 कार्य समाप्त हो जाएगा, तो उसका धागा 10 सेकंड के लिए पूल में रहेगा, उसके बाद उस धागे को समाप्त कर दिया जाएगा।
कॉमन्सवेयर

1
@ श्रीकांतकर्मनघाट: "मेरा सवाल है कि क्या समानांतर में 20 (कहते हैं) AsyncTasks चलाने के लिए कोई प्रतिबंध है?" - AsyncTaskआज का महत्वपूर्ण उपयोग करना एक शानदार योजना नहीं है। 20+ होने पर जो 10+ सेकंड के लिए चल सकता है, वह एक प्रकार की चीज़ है जिसे कोड समीक्षा में विफल होना चाहिए। यदि आप तेजी से उत्तराधिकार में 20 कार्य बनाते हैं, तो केवल कुछ ही समय पर चलेंगे, और शेष बाद के निष्पादन के लिए कतारबद्ध होंगे। सीपीयू के कोर की संख्या के आधार पर एक बार में कितने चलेंगे। AFAIK, वर्तमान एल्गोरिथ्म 2N + 1 समानांतर धागे हैं, जहां एन कोर की संख्या है।
कॉमन्सवेयर

24

कॉमन्सवेयर की प्रतिक्रिया के अलावा:

वर्तमान में मैं Android 2.2 का उपयोग कर रहा हूं, और मेरा एप्लिकेशन किसी भी समय एक से अधिक AsyncTask का उपयोग नहीं करता है, लेकिन मैं हर x मिनट में एक नया बना रहा हूं। पहले नए AsyncTask थ्रेड दिखाई देने लगते हैं (एक नए AsyncTask के लिए एक नया थ्रेड), लेकिन 5 थ्रेड्स (जैसा कि कॉमन्सवेयर द्वारा उल्लेख किया गया है) के बाद वे डिबग विंडो में केवल दिखाई देते हैं, और नए As AsTTask थ्रेड्स की आवश्यकता होने पर पुनः उपयोग में लाते हैं। वे वहीं रहते हैं जब तक डिबगर डिस्कनेक्ट नहीं हो जाता।


2
हां, पुष्टि की गई: मुझे 5 से अधिक AsyncTasks नहीं दिखता है।
सेराफिम का

3

एक ही लक्षण यहाँ। मेरे मामले में सूत्र ने गतिविधि को मारने के बाद चारों ओर लटके हुए थे, और मैं ऐप के पूरी तरह से बंद होने की उम्मीद कर रहा था। एकल थ्रेडेड निष्पादक का उपयोग करके समस्या को आंशिक रूप से हल किया गया:

    myActiveTask.executeOnExecutor(Executors.newSingleThreadExecutor());

इसने अपना काम पूरा करने के बाद धागे को गायब कर दिया।


इस जवाब ने AsyncTask को चलाने के बाद दूर कर दिया, शायद यह "सामान करने का Google तरीका" नहीं है, लेकिन यह काम पूरा करता है। धन्यवाद।
हेनरिक डी सोसा

इसने मेरी विशिष्ट समस्या को एक ही धागे पर एसिंक्शंस चलाने के बारे में हल किया।
कानून गिम्नेज

0

ThreadPoolExecutor का उपयोग करें ।

BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
ThreadPoolExecutor executor = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),       // Initial pool size
            Runtime.getRuntime().availableProcessors(),       // Max pool size
            1, // KEEP_ALIVE_TIME
            TimeUnit.SECONDS, //  KEEP_ALIVE_TIME_UNIT
            workQueue);

निष्पादित () विधि Runnableका उपयोग करके अपने कार्य को पोस्ट करें ।

void execute (Runnable command)

भविष्य में किसी समय दिए गए कार्य को निष्पादित करता है। कार्य एक नए थ्रेड या किसी मौजूदा थ्रेडेड थ्रेड में निष्पादित हो सकता है

आपकी दूसरी क्वेरी के बारे में:

मैं इन धागों को कैसे मार सकता हूँ?

एक बार जब आप अपने सभी कार्यों को पूरा कर लेते हैं ThreadPoolExecutor, तो इसे नीचे दिए गए पोस्ट के अनुसार ठीक से बंद कर दें:

कैसे ठीक से जावा ExecutorService बंद करने के लिए

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.