2008-08-28 17 views
36

मैं जावा में एक resetable समय के साथ java.utils.Timer रखना चाहता हूँ। मुझे एक्स सेकंड में एक बार ऑफ घटना होने की आवश्यकता है। यदि टाइमर बनाया गया था और एक्स सेकंड के बीच कुछ भी नहीं होता है, तो घटना सामान्य के रूप में होती है।रीसेट करने योग्य जावा टाइमर

यदि, हालांकि, एक्स सेकंड बीत जाने से पहले, मैं तय करता हूं कि घटना इसके बजाय वाई सेकंड के बाद होनी चाहिए, तो मैं टाइमर को अपना समय रीसेट करने में सक्षम होना चाहता हूं ताकि ईवेंट वाई सेकंड में हो। ईजी। टाइमर की तरह कुछ करने के लिए सक्षम होना चाहिए:

Timer timer = new Timer(); 
timer.schedule(timerTask, 5000); //Timer starts in 5000 ms (X) 

//At some point between 0 and 5000 ms... 
setNewTime(timer, 8000); //timerTask will fire in 8000ms from NOW (Y). 

मैं, इस utils टाइमर का उपयोग करने के लिए एक रास्ता नहीं दिख रहा है के रूप में यदि आप रद्द फोन() आप इसे फिर से शेड्यूल नहीं कर सकते।

इस व्यवहार को दोहराने के करीब आने का एकमात्र तरीका javax.swing.Timer का उपयोग करके और मूल टाइमर को रोकने और एक नया निर्माण करना शामिल है। i.e .:

timer.stop(); 
timer = new Timer(8000, ActionListener); 
timer.start(); 

क्या कोई आसान तरीका है ??

उत्तर

48

Timer दस्तावेज के अनुसार, जावा 1.5 में, आपको इसके बजाय ScheduledThreadPoolExecutor पसंद करना चाहिए। (आप इस निष्पादक उपयोग में आसानी के लिए Executors.newSingleThreadScheduledExecutor() का उपयोग कर बनाने के लिए पसंद कर सकते हैं;। यह कुछ ज्यादा एक Timer की तरह बनाता है) जब आप एक काम का निर्धारण करें (schedule() फोन करके)

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

ईटीए:

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

+0

ScheduledThreadPoolExecutor इस टाइमर में के बारे में बात कर रहा है: http://developer.android.com/reference/java/util/Timer.html इस दृष्टिकोण के साथ –

+0

मुद्दा यह है कि तुम अब 'TimerTask के लिए उपयोग किया है आपके कार्य के अंदर .scheduledExecutionTime() '। आप यह निर्धारित करने में सक्षम नहीं होंगे कि कार्य "मंद" है और निष्पादित नहीं होना चाहिए। –

+2

'myScheduledThreadPoolExecutor.getQueue()। सभी अनुसूचित कार्यों को निकालने के लिए साफ़()' का उपयोग करें जो अभी तक नहीं चल रहे हैं लेकिन आप इस तकनीक का उपयोग 'execors.newSingleThreadScheduledExecutor()' के साथ नहीं कर सकते हैं, आपको एक नया अनुसूचित थ्रेडपूल एक्स्सेलर को तुरंत चालू करना होगा (1) 'क्योंकि निष्पादक द्वारा लौटाई गई वस्तु पर केवल इंटरफेस विधियों का खुलासा किया जाता है। – gMale

1

क्या आपको आवर्ती कार्य निर्धारित करने की आवश्यकता है? उस स्थिति में मैं आपको Quartz का उपयोग करने पर विचार करने की सलाह देता हूं।

1

मुझे नहीं लगता कि Timer/TimerTask के साथ ऐसा करना संभव है, लेकिन आप जो हासिल करना चाहते हैं उसके आधार पर आप java.util.concurrent.ScheduledThreadPoolExecutor का उपयोग करके खुश रह सकते हैं।

17

अपने Timer ही कभी तो निष्पादित करने के लिए एक कार्य करने जा रहा है, तो मैं इसे उपवर्गीकरण का सुझाव देते हैं:

import java.util.Timer; 
import java.util.TimerTask; 

public class ReschedulableTimer extends Timer 
{ 
    private Runnable task; 
    private TimerTask timerTask; 

    public void schedule(Runnable runnable, long delay) 
    { 
     task = runnable; 
     timerTask = new TimerTask() 
     { 
      @Override 
      public void run() 
      { 
       task.run(); 
      } 
     }; 
     this.schedule(timerTask, delay); 
    } 

    public void reschedule(long delay) 
    { 
     timerTask.cancel(); 
     timerTask = new TimerTask() 
     { 
      @Override 
      public void run() 
      { 
       task.run(); 
      } 
     }; 
     this.schedule(timerTask, delay); 
    } 
} 

आप, गलत उपयोग के लिए जाँच करता है जोड़ने के लिए कोड पर काम करने की आवश्यकता होगी, लेकिन यह आपको प्राप्त करना चाहिए। प्रतीत होता है कि ScheduledThreadPoolExecutor मौजूदा कार्यों को फिर से निर्धारित करने के लिए समर्थन में नहीं बनाया गया है, लेकिन एक समान दृष्टिकोण भी वहां काम करना चाहिए।

1

यही वह है जिसे मैं कोशिश कर रहा हूं। मेरे पास एक कक्षा है जो टाइमर टास्क का उपयोग करते हुए हर 60 सेकंड में डेटाबेस का चुनाव करती है।

मेरी मुख्य कक्षा में, मैं टाइमर का उदाहरण रखता हूं, और टाइमरटास्क के अपने स्थानीय उप-वर्ग का उदाहरण देता हूं। मुख्य वर्ग में मतदान अंतराल (60 से 30 तक जाने का कहना है) सेट करने का एक तरीका है। इसमें, मैं अपना टाइमरटास्क रद्द करता हूं (जो मेरा सबक्लास है, जहां मैं कुछ सफाई करने के लिए रद्द() विधि को ओवरराइट करता हूं, लेकिन इससे कोई फर्क नहीं पड़ता) और फिर इसे शून्य बनाते हैं। मैं इसका एक नया उदाहरण दोबारा तैयार करता हूं, और मौजूदा टाइमर में नए अंतराल पर नया उदाहरण निर्धारित करता हूं।

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

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

3

पूरे कोड स्निपेट इस तरह से चला जाता है .... मुझे आशा है कि यह यहाँ मदद की जाएगी पूर्ण

{ 

     Runnable r = new ScheduleTask(); 
     ReschedulableTimer rescheduleTimer = new ReschedulableTimer(); 
     rescheduleTimer.schedule(r, 10*1000); 


    public class ScheduleTask implements Runnable { 
     public void run() { 
      //Do schecule task 

     } 
     } 


class ReschedulableTimer extends Timer { 
     private Runnable task; 
     private TimerTask timerTask; 

     public void schedule(Runnable runnable, long delay) { 
      task = runnable; 
      timerTask = new TimerTask() { 
       public void run() { 
        task.run(); 
        } 
       }; 

      timer.schedule(timerTask, delay);   
     } 

     public void reschedule(long delay) { 
      System.out.println("rescheduling after seconds "+delay); 
      timerTask.cancel(); 
      timerTask = new TimerTask() { 
       public void run() { 
        task.run(); 
       } 
      }; 
      timer.schedule(timerTask, delay);   
     } 
     } 


} 
0

resetable टाइमर के लिए उदाहरण है। अपने convinence के लिए इसे बदलने के लिए ...

package com.tps.ProjectTasks.TimeThread; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.Timer; 
import java.util.TimerTask; 

/** 
* Simple demo that uses java.util.Timer to schedule a task to execute 
* every 5 seconds and have a delay if you give any input in console. 
*/ 

public class DateThreadSheduler extends Thread { 
    Timer timer; 
    BufferedReader br ; 
    String data = null; 
    Date dNow ; 
    SimpleDateFormat ft; 

    public DateThreadSheduler() { 

     timer = new Timer(); 
     timer.schedule(new RemindTask(), 0, 5*1000); 
     br = new BufferedReader(new InputStreamReader(System.in)); 
     start(); 
    } 

    public void run(){ 

     while(true){ 
      try { 
       data =br.readLine(); 
       if(data != null && !data.trim().equals("")){ 
        timer.cancel(); 
        timer = new Timer(); 
        dNow = new Date(); 
        ft = new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz"); 
        System.out.println("Modified Current Date ------> " + ft.format(dNow)); 
        timer.schedule(new RemindTask(), 5*1000 , 5*1000); 
       } 

      }catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public static void main(String args[]) { 
     System.out.format("Printint the time and date was started...\n"); 
     new DateThreadSheduler(); 
    } 
} 

class RemindTask extends TimerTask { 
    Date dNow ; 
    SimpleDateFormat ft; 

    public void run() { 

     dNow = new Date(); 
     ft = new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz"); 
     System.out.println("Current Date: " + ft.format(dNow)); 
    } 
} 

यह उदाहरण हर 5 सेकंड के लिए वर्तमान दिनांक और समय प्रिंट का प्रयास करें ... लेकिन अगर आप कंसोल में किसी भी इनपुट दे टाइमर दिए गए इनपुट प्रदर्शन करने के लिए विलंब होगा कार्य ...

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