टिमर और टाइमर बनाम थ्रेड + जावा में सोते हैं


102

मुझे यहां पूछे गए समान प्रश्न मिले लेकिन मेरी संतुष्टि के जवाब नहीं थे। तो सवाल को फिर से दोहराते हुए-

मेरे पास एक कार्य है जिसे आवधिक आधार पर करने की आवश्यकता है (1 मिनट के अंतराल पर)। नींद के साथ अनंत लूप वाले एक नए धागे को बनाने के विरोध में ऐसा करने के लिए टिमर्टस्क और टाइमर का उपयोग करने का क्या फायदा है?

कोड स्निपेट टाइमटेस्क का उपयोग करते हुए-

TimerTask uploadCheckerTimerTask = new TimerTask(){

 public void run() {
  NewUploadServer.getInstance().checkAndUploadFiles();
 }
};

Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(uploadCheckerTimerTask, 0, 60 * 1000);

थ्रेड और नींद का उपयोग करके कोड स्निपेट-

Thread t = new Thread(){
 public void run() {
  while(true) {
   NewUploadServer.getInstance().checkAndUploadFiles();
   Thread.sleep(60 * 1000);
  }
 }
};
t.start();

मुझे वास्तव में चिंता करने की ज़रूरत नहीं है अगर मुझे कुछ चक्रों की याद आती है यदि तर्क का निष्पादन अंतराल समय से अधिक होता है।

कृपया इस पर टिप्पणी करें ।।

अद्यतन:
हाल ही में मुझे टाइमर बनाम थ्रेड। स्लीप () का उपयोग करने के बीच एक और अंतर मिला। मान लीजिए कि वर्तमान प्रणाली का समय सुबह 11:00 बजे है। अगर हम किसी कारणवश सिस्टम टाइम को 10:00 AM तक रोलबैक करते हैं, तो द टाइमर 11:00 AM तक कार्य को अंजाम देगा, जबकि थ्रेड। स्लीप () विधि कार्य को बिना बाधा के निष्पादित करना जारी रखेगी। यह निर्णय लेने में एक प्रमुख निर्णय निर्माता हो सकता है कि इन दोनों के बीच क्या उपयोग किया जाए।


21
पॉइंट ऑफ़ ऑर्डर: टाइमर और टाइमरर अप्रचलित हैं, और प्रभावी रूप से एक्सेलसॉर सर्विस द्वारा प्रतिस्थापित किया गया है, हालाँकि आपकी बात अभी भी कायम है।
स्केफमैन

टिप के लिए धन्यवाद, मैंने ExecutorService का उपयोग करने का फैसला किया :)
केशव

जवाब के लिए आप सभी को धन्यवाद, निश्चित रूप से मुझे अधिक समझ दी गई!
केशव

6
टाइमर अप्रचलित नहीं है, और पसंद किया जाता है जब केवल एक ही धागे की आवश्यकता होती है। ( java.sun.com/javase/6/docs/api/java/util/Timer.html )
जस्टिन

2
टाइमर और टाइमर अभी भी JME वातावरण में उपयोगी हैं, जहां एक्सेकॉर्स सर्विस मौजूद नहीं है (चूंकि JME जावा 1.3 आधारित ...)।
ァ パ ー フ ミ コ

जवाबों:


67

TimerTask का लाभ यह है कि यह आपके इरादे को बहुत बेहतर (अर्थात कोड पठनीयता) व्यक्त करता है, और इसमें पहले से ही रद्द () सुविधा लागू है।

ध्यान दें कि इसे छोटे रूप में और साथ ही अपने स्वयं के उदाहरण में लिखा जा सकता है:

Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(
    new TimerTask() {
      public void run() { NewUploadServer.getInstance().checkAndUploadFiles(); }
    }, 0, 60 * 1000);

यदि टाइमर का उपयोग हर दिन के लिए किया जाता है, तो 2 विशिष्ट समय 9:00 और 9 बजे, ... मान कैसे दें? ऊपर दिए गए कोड पर ... @Zed?
गमरु

12

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


5

मुझे पता नहीं क्यों लेकिन एक कार्यक्रम जो मैं लिख रहा था वह टाइमर का उपयोग कर रहा था और यह ढेर का आकार लगातार बढ़ रहा था, एक बार मैंने इसे थ्रेड / स्लीप समस्या में बदल दिया।


9
टाइमर लगातार अद्यतन किए जाने वाले कार्यों की एक कतार बनाता है। जब टाइमर किया जाता है, तो यह तुरंत कचरा एकत्र नहीं किया जा सकता है। इसलिए अधिक टाइमर बनाना केवल ढेर पर अधिक ऑब्जेक्ट जोड़ता है। थ्रेड। स्लीप () केवल थ्रेड को रोक देता है, इसलिए मेमोरी ओवरहेड बेहद कम होगी।
डेरिल गेरो सेप

4

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


4

से Timer प्रलेखन :

जावा 5.0 ने java.util.concurrent पैकेज पेश किया और उसमें एक संगणकीय उपयोगिताओं में से एक है शेड्यूलट्रेडपूल एक्सक्यूटोरर जो किसी दिए गए दर या देरी पर बार-बार कार्यों को निष्पादित करने के लिए एक थ्रेड पूल है। यह प्रभावी रूप से टाइमर / टाइमरस्क कॉम्बिनेशन के लिए एक अधिक बहुमुखी प्रतिस्थापन है, क्योंकि यह कई सर्विस थ्रेड्स को अनुमति देता है, विभिन्न समय इकाइयों को स्वीकार करता है, और टाइमररस्क (बस रननेबल लागू करने) की आवश्यकता नहीं होती है। ScheduledThreadPoolExecutor को एक थ्रेड के साथ कॉन्फ़िगर करना इसे टाइमर के समतुल्य बनाता है।

इसलिए ScheduledThreadExecutorइसके बजाय प्राथमिकता दें Timer:

  • Timerसिंगल बैकग्राउंड थ्रेड का उपयोग करता है जो कि टाइमर के सभी कार्यों को क्रमिक रूप से निष्पादित करने के लिए उपयोग किया जाता है। इसलिए कार्यों को जल्दी से पूरा करना चाहिए अन्यथा यह बाद के कार्यों के निष्पादन में देरी करेगा। लेकिन ScheduledThreadPoolExecutorहम किसी भी संख्या में थ्रेड को कॉन्फ़िगर कर सकते हैं और प्रदान करके पूर्ण नियंत्रण भी रख सकते हैं ThreadFactory
  • Timerसिस्टम घड़ी के प्रति संवेदनशील हो सकता है क्योंकि यह Object.wait(long)विधि का उपयोग करता है । लेकिन ScheduledThreadPoolExecutorनहीं है।
  • टिमरटेक में फेंके गए रनटाइम अपवाद उस विशेष धागे को मार देंगे, इस प्रकार टाइमर को मृत बना देगा जहां हम संभाल सकते हैं ScheduledThreadPoolExecutorताकि अन्य कार्य प्रभावित न हों।
  • Timercancelटाइमर को समाप्त करने और किसी भी निर्धारित कार्य को छोड़ने के लिए विधि प्रदान करता है, हालांकि यह वर्तमान में निष्पादित कार्य में हस्तक्षेप नहीं करता है और इसे खत्म करने देता है। लेकिन अगर टाइमर डेमन थ्रेड के रूप में चल रहा है तो हम इसे रद्द करते हैं या नहीं, यह समाप्त हो जाएगा जैसे ही सभी उपयोगकर्ता थ्रेड निष्पादित हो जाते हैं।

टाइमर बनाम थ्रेड। सो

टाइमर का उपयोग करता है Object.waitऔर यह अलग हैThread.sleep

  1. एक प्रतीक्षा ( wait) धागा को notifyदूसरे धागे से अधिसूचित (उपयोग ) किया जा सकता है लेकिन एक नींद नहीं हो सकती है, यह केवल बाधित हो सकता है।
  2. एक प्रतीक्षा (और सूचित) मॉनिटर ऑब्जेक्ट पर सिंक्रनाइज़ किए गए ब्लॉक में होना चाहिए, जबकि नींद नहीं होती है।
  3. जबकि सो लॉक को रिलीज नहीं करता है, वेटिंग के लिए लॉक जारी किया जाएगा।

बहुत उपयोगी जानकारी, एक अनंत लूप में Thread.sleep का उपयोग करने से कम समय की देरी में उच्च CPU उपयोग हो सकता है।
आमिर फेन

3

जावा थ्रेड और sleepविधि का उपयोग करके इस कार्य को प्रबंधित करने के खिलाफ एक महत्वपूर्ण तर्क है । आप while(true)लूप में अनिश्चित काल तक रहने के लिए उपयोग कर रहे हैं और नींद को लगाकर धागे को हाइबरनेट करते हैं। क्या होगा अगर NewUploadServer.getInstance().checkAndUploadFiles();कुछ सिंक्रनाइज़ संसाधनों को लेता है। अन्य सूत्र इन संसाधनों तक पहुंचने में असमर्थ होंगे, भुखमरी हो सकती है जो आपके पूरे आवेदन को धीमा कर सकती है। इस प्रकार की त्रुटियों का निदान करना कठिन है और उनकी मौजूदगी को रोकने के लिए यह एक अच्छा विचार है।

अन्य aproach उस कोड के निष्पादन को ट्रिगर करता है जो आपके लिए मायने रखता है, अर्थात इस बीच संसाधनों का उपयोग करते हुए अन्य थ्रेड्स देते हुए अपने तरीके को NewUploadServer.getInstance().checkAndUploadFiles();कॉल करना ।run()TimerTask


16
मैं इस तर्क को नहीं समझता। दोनों विकल्प थ्रेड से एक ही विधि को लॉन्च करते हैं, दोनों विकल्प थ्रेड में सो रहे होते हैं जब वे निष्पादित करने की प्रतीक्षा करते हैं। दो विकल्पों के बीच कोई भुखमरी अंतर नहीं होगा।
satur9nine

2

मुझे लगता है कि मैं आपके मुद्दे को समझता हूं, मैं कुछ इसी तरह देख रहा हूं। मेरे पास बार-बार आने वाले समय हैं, हर 30 मिनट में और कुछ हर दिन। मैं जो भी पढ़ता हूं और जो टिप्पणियां देखता हूं, ऐसा लगता है कि कचरा संग्रह कभी नहीं चलेगा क्योंकि सभी कार्य कभी पूरे नहीं होते हैं। मुझे लगता है कि कचरा संग्रह तब चलेगा जब एक टाइमर नींद में होगा, लेकिन मैं इसे नहीं देख रहा हूं और प्रलेखन के अनुसार यह नहीं है।

मुझे लगता है कि नए धागों को पूरा करने से कचरा इकट्ठा हो जाता है।

किसी ने मुझे गलत साबित कर दिया है, जो मुझे विरासत में मिला है वह एक दर्द होने वाला है।

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