2010-06-16 15 views
5

मेरे पास एक कक्षा है जो थ्रेड क्लास को बढ़ाती है और इसकी रन विधि को लागू किया गया है।एंड्रॉइड थ्रेड प्रबंधन पर

public void run(){ 
    while(!terminate){ 
     if(paused){ 
      Thread.yield(); 
     }else{ 
      accummulator++; 
     } 
    } 
} 

यह धागा ऑनक्रेट विधि से उत्पन्न होता है।

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

तो मेरा सवाल है। थ्रेड को रोकने का सही तरीका क्या है ताकि यह CPU समय का उपयोग न करे?

उत्तर

4

यह वास्तव में खराब चल रहा है ताकि थ्रेड चलने के बाद चल रहा हो। इसका कारण यह है कि चूंकि आपका आवेदन किसी भी समय आपकी जानकारी के बिना मेमोरी से बाहर हो सकता है, इसलिए आप अपने बाद साफ नहीं कर पाएंगे।

ऐसा करने का उचित तरीका थ्रेड को रोक रहा है और इसे फिर से शुरू कर रहा है। अगर आपको राज्य की आवश्यकता है तो आप एंड्रॉइड के सेवस्टेट विधियों या सेटिंग्स या जो भी इसे रखने के लिए इस्तेमाल कर सकते हैं।

+0

हां, यह निष्कर्ष है कि मैं भी साथ आया था। इसके अतिरिक्त मुझे लगता है कि कार्यान्वयन का सर्वोत्तम तरीका सीधे थ्रेड से उप-वर्ग नहीं है बल्कि रननेबल इंटरफ़ेस का उपयोग करना है। इस तरह आप धागे को मार सकते हैं लेकिन अभी भी राज्य खोने के बिना, एक और थ्रेड को तुरंत चालू करके "फिर से शुरू करने" की क्षमता है। अनुमोदित है कि ऑनस्ट्रोय या एप्लिकेशन को मार डाला और पुनर्निर्मित नहीं किया गया है। –

0

आपके paused परिवर्तनीय को स्थानीय स्तर पर कैश किए जाने की संभावना है। ऐसा इसलिए है क्योंकि इसे केवल लूप में पढ़ा और बदला नहीं जा रहा है। तो क्या हो रहा है कि संकलक/दुभाषिया/जिटर केवल एक बार वैरिएबल को पढ़कर अनुकूलित करता है और फिर केवल else शाखा निष्पादित करता है। आपको pause वैरिएबल के लिए लूप के माध्यम से प्रत्येक पुनरावृत्ति को पढ़ने के लिए volatile के रूप में उस फ़ील्ड को चिह्नित करने की आवश्यकता है। volatile कीवर्ड के documentation देखें। यहां some info about threading और some info about synchronization and concurrency है।

+0

मैं रोके गए परिवर्तनीय कब्जे वाले संसाधनों के बारे में बहुत चिंतित नहीं हूं। मैं चिंतित हूं कि यूआई थ्रेड बंद होने के बावजूद धागा अभी भी लूपिंग कर रहा है। –

+0

मैंने जवाब को अद्यतन किया है कि क्या हो रहा है यह स्पष्ट रूप से समझाएं। जवाब विराम चर और संसाधनों के बारे में नहीं था। थ्रेड अभी भी लूपिंग है क्योंकि रोके गए चर को अस्थिर के रूप में चिह्नित नहीं किया गया है और फिर से पढ़ा नहीं जा रहा है। यह बहु-थ्रेडेड प्रोग्रामिंग की सूक्ष्मता में से एक है। – Qberticus

1

भले ही आप thread.yield() को कॉल कर रहे हों, आप थोड़ी देर के अंदर() लूप के अंदर हैं जो शायद प्रति सेकंड हजारों बार लूपिंग कर रहा है, हर बार .yield() लेकिन यह तथ्य कि यह लूपिंग है नियंत्रण का मतलब है कि यह संसाधनों का उपयोग कर रहा है। यदि आप वहां Log.d संदेश डालते हैं तो आप देखेंगे कि मेरा क्या मतलब है।

मैं Thread.yield() के बजाय Thread.sleep() का उपयोग करने की सलाह देता हूं। कारण यह है कि एक धागा सो रहा है, यह पैदा होता है। इसके अलावा नींद के साथ आपको while() धीमा करने और संसाधनों का उपयोग न करने का अतिरिक्त लाभ मिलता है। 500ms का नींद अंतराल पर्याप्त होना चाहिए =)

+0

थ्रेड अंततः कैनवास पर रेंडर थ्रेड के रूप में उपयोग किया जाएगा और इसे जितनी जल्दी हो सके निष्पादित करना चाहिए। मुझे लगता है कि मैं धागे को मारने और ऑनर्स हैंडलर –

+0

में इसे पुन: प्रयास करने की कोशिश करने जा रहा हूं। यह जोर देने योग्य है कि आपके कोड में बंद की तरह बंद लूप सीपीयू हॉग हैं। एक मोबाइल डिवाइस पर, एक सीपीयू हॉग जल्दी में बैटरी खाएगा। –

+0

मुझे 'थ्रेड.इल्ड' (उर्फ 'थ्रेड स्लीप (0)') और उच्च प्रोसेसर उपयोग के साथ कोई समस्या नहीं है - थ्रेड शेड्यूलर में न्यूनतम ग्रैन्युलरिटी * * प्रति सेकंड हजारों बार "से नीचे है। –

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