2012-03-21 13 views
7

के लिए अच्छा अभ्यास मेरे पास एक ऐप है जहां एक "गेम" आंकड़े, यह दो अलग-अलग धागे शुरू करता है। मैं बहुत की तरह धागे शुरू:बहु-थ्रेडिंग

Thread thread = new Thread(new Runnable() 
{ 
    public void run() 
    { 
     //... 
    } 
}); 

thread.setName("killMeAtEnd"); 
thread.start(); 

बाद में जब खेल समाप्त होता है मैं खेल के अंदर एक निपटाने() विधि जो चल धागे के सभी के माध्यम से क्रमबद्ध करता और धागे का नाम "killMeAtEnd" है कि सब समाप्त हो जाती है है । मेरा सवाल है, क्या यह अच्छा अभ्यास है? मेरा इरादा है कि मेरे ऐप को तेजी से और अव्यवस्थित मुक्त चलाना है, मेरे अनुभव में थ्रेड जो "लटकते" हैं, ऐप समाप्त होने तक फ़ोन को धीमा कर देते हैं। क्या ऐसा करने के लिए इससे अच्छा तरीका है? क्या यह भी परेशान करने लायक है?

संपादित करें:

यहाँ मेरी dispose() अगर कोई दिलचस्पी थी है। यह कोड कक्षा गेम के भीतर है।

public void dispose() 
{ 
    Thread threads[] = (Thread[])Thread.getAllStackTraces().keySet().toArray(); 
    for(int x=0;x<threads.length;x++) 
    { 
     Thread thread = threads[x]; 
     if(thread.getName().equalsIgnoreCase(KILL)) 
     { 
      try 
      { 
       thread.interrupt(); 
      }catch(Exception e){Log.e(Viewer.GAME,Log.getStackTraceString(e));} 
      thread = null; 
     } 
    } 
} 

public static final String KILL = "endOnDispose"; 
+0

स्टैकट्रैक प्राप्त करना काफी महंगा है, इसलिए यदि आप धागे बनाते हैं और इसे 'निपटाना [थ्रेड [] धागे) बनाते हैं तो यह अधिक कुशल होगा यदि आप' धागे [] 'को सहेज लेंगे। क्या कोई अन्य धागे चल रहा है जब आपका गेम समाप्त होता है या यह आपको यूआई थ्रेड को मारने से रोकने के लिए है? – zapl

+0

जब गतिविधि पर "गेम" खत्म हो जाता है, तो यह कुछ और नहीं चलता है। मदद के लिए – John

उत्तर

4

आप सही पता नहीं है, लेकिन वहाँ सुधार के लिए कुछ क्षेत्र हैं:

  1. इसके बजाय के लिए चल रहे सभी धागे प्रणाली की क्वेरी, जब भी आप उन्हें बनाने के लिए सिर्फ एक सूची में अपने सूत्र को जोड़ने की। फिर आप अपने द्वारा बनाए गए सभी धागे को समाप्त कर सकते हैं या उनके पूरा होने (प्रतीक्षा) के लिए प्रतीक्षा कर सकते हैं।
  2. इंटरप्ट केवल अवरुद्ध स्थिति में एक थ्रेड को बाधित करता है, इसलिए आपको समय-समय पर थ्रेड जांचने की आवश्यकता होती है (यानी प्रत्येक "कार्य चक्र" के बाद)।
  3. अपने धागे के अंदर इंटरप्ट अपवाद को पकड़ें और इसे संभाल लें (यानी खूबसूरती से बाहर निकलें)।
+0

+1 धन्यवाद! मैंने अपने सभी धागे को एक सूची में डाल दिया और फिर गेम को पूरा करने के बाद उन्हें मार दिया। – John

3

यह जरूरी एक बुरा समाधान नहीं है, लेकिन कुछ मुद्दे हैं:

  • अपने धागे तरह की कार्यकर्ता धागे कि पूरा करने के लिए एक कार्य संभाल रहे हैं, वहाँ है संभवतः एक बेहतर डिजाइन जिसमें थ्रेड स्वयं समाप्त होता है। दूसरे शब्दों में, संभवतः निष्पादन का बेहतर प्रवाह होता है, जिसके लिए अंत में मारे जाने की आवश्यकता नहीं होती है।

  • जब आप कहते हैं "सभी चल रहे थ्रेड के माध्यम से सॉर्ट करें ...", मुझे लगता है कि आप JVM में सभी चल रहे थ्रेड देख रहे हैं? this SO question की तर्ज पर कुछ के रूप में? यदि ऐसा है, तो आप केवल उन सभी धागे का संदर्भ क्यों नहीं रखते हैं जिनके आपके गेम का स्वामित्व है, और फिर उन्हें विशेष रूप से मारना? "KillMeAtEnd" की तलाश करने के विरोध में; मैं नहीं सोच सकता कि आपकी रणनीति कैसे गलत हो सकती है, लेकिन यह आपके धागे का ट्रैक रखने के लिए थोड़ा क्लीनर लगता है।

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

+0

+1 धन्यवाद! – John

0

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

अपने सभी थ्रेड कार्य निष्पादक सेवा के लिए करें।

जब खेल समाप्त होता है, तो shutdownNow का उपयोग कर निष्पादक सेवा को बंद कर दें। यह निष्पादक सेवा में सभी धागे को बाधित करने में बाधा डाल देगा।जब आप एक नया गेम शुरू करते हैं तो आप एक नया एक्जिक्यूटर्स सेवा बना सकते हैं।

यदि थ्रेड की संख्या तय की गई है तो आप निष्पादक सेवा बनाने के लिए execors.newFixedThreadPool() का उपयोग कर सकते हैं।

यदि थ्रेड की संख्या परिवर्तनीय है तो आप निष्पादक सेवा बनाने के लिए execors.newCachedThreadPool का उपयोग कर सकते हैं।