2016-05-06 7 views
6

हाल ही में मैंने एक बहुत ही बुनियादी कार्यक्रम बनाया है। एक समय काउंटर जिसमें रुकने की क्षमता है। यह 3 धागे, स्विंग के लिए 2 और मुख्य धागे के लिए 1 के साथ काम कर रहा था।जबकि (सच) लूप या java.util.Timer एक मानक प्रोग्राम पाश के लिए?

इस कार्यक्रम के लिए मुख्य धागे में एक डेल्टा समय गिनती हिस्सा होना चाहिए। मैंने इस तरह की एक बहुत ही बुनियादी प्रणाली बनाई;

while(true) 
{ 
    long now = System.currentTimeMillis(); 

    if(!sessionPaused) 
    { 
     if(now-programLastMs>1000) 
     { 
      save(); 
      programLastMs = now; 
     } 
     sessionMs += now-sessionPrevMs; 
     overallMs += now-sessionPrevMs; 

     sessionPrevMs = now; 
     sessionLabel.setText(formatMillis("This Session:<br/>",sessionMs)); 
     overallLabel.setText(formatMillis("Overall:<br/>", overallMs)); 
    } 
} 

उपरोक्त यह कोड उच्च CPU उपयोग के कारण हुआ। मैं तो साथ कि कोड हिस्सा लिया है:

timer.scheduleAtFixedRate(new TimerTask() { 
      @Override 
      public void run() { 

       long now = System.currentTimeMillis(); 

       if(!sessionPaused) 
       { 
        if(now-programLastMs>1000) 
        { 
         save(); 
         programLastMs = now; 
        } 

        sessionMs += now-sessionPrevMs; 
        overallMs += now-sessionPrevMs; 

        sessionPrevMs = now; 

        sessionLabel.setText(formatMillis("This Session:<br/>",sessionMs)); 
        overallLabel.setText(formatMillis("Overall:<br/>", overallMs)); 
       } 
      } 
     }, 0, 1); 

और समस्या चला गया था। मुझे बस इसका कारण आश्चर्य है। प्रोग्राम लूप बनाने का इष्टतम तरीका भी क्या है?

+3

आपका 'जबकि (सत्य) 'लूप कोई रोक नहीं देता है, इसलिए लूप लगातार चल रहा है और लगातार सीपीयू खा रहा है। शेड्यूलिंग आपके 'रन' विधि को निष्पादित करती है, केवल तभी जब इसे निर्धारित किया जाता है। – Berger

+0

तो अगर मैंने शेड्यूलर को 50 नैनोसेकंड प्रति बार एक बार कॉल किया है, तो क्या यह वही होगा?और फिर भी प्रोग्राम लूप बनाने का सबसे अच्छा तरीका क्या है? @ बर्गर – iGoodie

+0

यह आपकी 'रन' विधि की अवधि पर निर्भर करता है, लेकिन 50 नैनोसेकंड वास्तव में कम है, क्या आपको ऐसी उच्च आवृत्ति की आवश्यकता है? हालांकि, जैसा कि आपने इसे देखा है, अपने एप्लिकेशन को सांस लेने देना बेहतर है, इसलिए या तो शेड्यूलर का उपयोग करें, या अपने 'जबकि' लूप में 'थ्रेड.sleep' जोड़ें। – Berger

उत्तर

5

आपका पहला कोड ब्लॉक मूल रूप से सीपीयू की गति से चलता है। इसे समझने के लिए, आपको यह जानना होगा कि IPS और FLOPS क्या हैं। एक आधुनिक सीपीयू कुछ GFLOPS करता है जिसका अर्थ है कि आपका पहला ब्लॉक आपके हार्डवेयर के आधार पर निष्पादित दस या हजारों बार प्रति सेकंड हो रहा है। यदि आप इसे मुख्य थ्रेड पर चलाते हैं, तो यह आपके यूआई को अवरुद्ध कर देगा (यानी आपका जीयूआई फंस जाएगा)। एक अलग धागे पर, यह वास्तव में बहुत कुछ किए बिना संसाधनों को लगातार चलाएगा।

दूसरी तरफ, दूसरी ब्लॉक में प्रत्येक मिलीसेकंड निष्पादित करने के लिए विशिष्ट निर्देश हैं। इसका मतलब है कि आपका कोड ब्लॉक 1000 बार निष्पादित किया गया है और शेष सीपीयू समय अन्य काम के लिए मुक्त हो गया है।

अपनी टिप्पणी में प्रश्न को हल करने के लिए: यह अनंत लूप का उपयोग करने के लिए लगभग स्वीकार्य नहीं है। लूप का सबसे अच्छा निर्देशों के एक सेट के बाध्य दोहराव के लिए उपयोग किया जाता है। आपके उदाहरण में, ऐसा लगता है कि आप हर 1000ms को सहेजना चाहते हैं और सत्र समय भी गिनना चाहते हैं। मैं

  1. प्रत्येक 1000ms नामक दोहराने वाले टाइमर को सहेजने के लिए अलग करें।
  2. ऑन-सत्रपॉज़ और सत्र सत्र पर बनाएं जो केवल विराम-स्थिति बदलता है। यह एक विराम बटन या किसी अन्य प्रकार की स्थिति के कारण हो सकता है जिसे आप परिभाषित करते हैं। ऑन सत्रपॉज़ और ऑनसेशन रेज़्यूम फ़ंक्शंस उस समय को रिकॉर्ड करने में सक्षम होना चाहिए जिस पर उन्हें कॉल किया जाता है और समय पर अंतर के आधार पर सत्र एम अपडेट किया जा सकता है।

जब तक आप प्रत्येक मिलीसेकंद को बदलने की अपेक्षा नहीं कर रहे हैं, तो आप सीपीयू को अनावश्यक काम कर रहे हैं।

+0

वह सही उत्तर था जिसे मैं ढूंढ रहा था। विस्तृत जानकारी के लिए धन्यवाद (वाई) – iGoodie

0

प्रोग्राम लूप बनाने का सबसे अच्छा तरीका क्या है?

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

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

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