如何使用Timer类调用方法,执行某些操作,重置计时器,重复?

时间:2012-02-23 13:04:54

标签: java timer scheduled-tasks

我是一名Java初学者,并且一直在寻找解决这个问题的各种解决方案,并且已经让自己变得紧张起来。我已经尝试过使用Threads,然后发现了这个Timer类,并且到目前为止没有成功。如果您可以使用主方法发布可执行代码,那么我可以看到它正常工作并从那里开始玩,这将是很棒的。

  1. 启动计划
  2. 致电doSomething()
  3. 生成随机数并设置那么长的计时器。
  4. 当计时器关闭时,再次致电doSomething()
  5. 可能使用此:http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html

6 个答案:

答案 0 :(得分:40)

如果你想简单地使用Timer,我会做这样的事情:

public class TestClass {
    public long myLong = 1234;

    public static void main(String[] args) {
        final TestClass test = new TestClass();

        Timer timer = new Timer();
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                test.doStuff();
            }
        }, 0, test.myLong);
    }

    public void doStuff(){
        //do stuff here
    }
}

抱歉糟糕的身份。

此外,如果您需要安排代码的执行,请查看Guava Services,因为它可以使您的代码更清晰,更抽象地创建线程,调度等等。

顺便说一句,我没有遇到生成随机数等的麻烦,但我认为你可以弄清楚如何包含那部分。我希望这足以让你走上正轨。

为了记录,如果您使用Guava,它看起来像这样:

class CrawlingService extends AbstractScheduledService {

    @Override
    protected void runOneIteration() throws Exception {
        //run this alot
    }

    @Override
    protected void startUp() throws Exception {
        //anything you need to step up
    }

    @Override
    protected void shutDown() throws Exception {
        //anything you need to tear down
    }


    @Override
    protected Scheduler scheduler() {
        return new CustomScheduler() {
            @Override
            protected Schedule getNextSchedule() throws Exception {
                long a = 1000; //number you can randomize to your heart's content
                return new Schedule(a, TimeUnit.MILLISECONDS);
            }
        };
    }
}

你只需创建一个名为new CrawlingService.start()的main;就是这样。

答案 1 :(得分:25)

你特别想要一个Timer吗?如果不是,您最好使用ScheduledExecutorService并致电scheduleAtFixedRatescheduleWithFixedDelay;引用Javadocs

  

Java 5.0引入了java.util.concurrent包和其中一个   其中的并发实用程序是ScheduledThreadPoolExecutor   是一个线程池,用于以给定的速率重复执行任务或   延迟。它实际上是一种更通用的替代品   Timer / TimerTask组合,因为它允许多个服务线程,   接受各种时间单位,不需要子类TimerTask   (只需实现Runnable)。配置ScheduledThreadPoolExecutor   使用一个线程使其等同于Timer

<强>更新

以下是使用ScheduledExecutorService的一些工作代码:

import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Test {
    public static void main(String[] args) {
        final ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
        ses.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                System.out.println(new Date());
            }
        }, 0, 1, TimeUnit.SECONDS);
    }
}

输出如下:

Thu Feb 23 21:20:02 HKT 2012
Thu Feb 23 21:20:03 HKT 2012
Thu Feb 23 21:20:04 HKT 2012
Thu Feb 23 21:20:05 HKT 2012
Thu Feb 23 21:20:06 HKT 2012
Thu Feb 23 21:20:07 HKT 2012

答案 2 :(得分:2)

考虑一种情况,我希望我的代码在我的应用程序中的特定时间执行,或者在当前时间稍后的某个时间执行。换句话说,我想在确定的时间安排我的任务。

Java Timer class(java.util.Timer)允许应用程序在单独的后台线程上安排任务。

这是最简单的example of Java Timer

import java.util.Timer;
import java.util.TimerTask;
public class JavaTimer {
  public static void main(String[] args){
  Timer timer = new Timer();
  TimerTask task = new TimerTask() {
      @Override
   public void run() {
    System.out.println("Inside Timer Task" + System.currentTimeMillis());
       }
  };

  System.out.println("Current time" + System.currentTimeMillis());
  timer.schedule(task, 10000,1000);
  System.out.println("Current time" + System.currentTimeMillis());

  }
}
Output:
Current time1455469505220
Current time1455469505221
Inside Timer Task1455469515222
Inside Timer Task1455469516222
Inside Timer Task1455469517222
Inside Timer Task1455469518222
Inside Timer Task1455469519222
Inside Timer Task1455469520222
Inside Timer Task1455469521222
Inside Timer Task1455469522222
Inside Timer Task1455469523222
Inside Timer Task1455469524222
Inside Timer Task1455469525222
Inside Timer Task1455469526222
Inside Timer Task1455469527222
Inside Timer Task1455469528223
Inside Timer Task1455469529223 and it goes on

分析: 对timer.schedule(任务,10000,1000)的调用将计划在此调用10秒后第一次(在另一个线程上)执行的任务。之后,它将在延迟10秒后再次呼叫。这里需要提一下的是,如果任务在10秒后无法启动,则下一个任务调用将无法获得预先池塘。所以这里两个连续任务之间的延迟时间是固定的。

来源:Java Timer Example

答案 3 :(得分:1)

如果您不想使用计时器类并且可以使用Quartz,那么就像执行它一样。我的主要课程是

import com.google.common.util.concurrent.AbstractScheduledService;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import static org.quartz.TriggerBuilder.newTrigger;

import java.util.concurrent.CountDownLatch;

public class Test {


    public static void main(String[] args) throws Exception{


        CountDownLatch latch = new CountDownLatch(1);


        //do schdeuling thing
        JobDetail job = JobBuilder.newJob(SimpleJob.class).withIdentity(
                "CronQuartzJob", "Group").build();

        // Create a Trigger that fires every 5 minutes.
        Trigger trigger = newTrigger()
                .withIdentity("TriggerName", "Group")
                .withSchedule(CronScheduleBuilder.cronSchedule("0/1 * * * * ?"))
                .build();

        // Setup the Job and Trigger with Scheduler & schedule jobs
        final Scheduler scheduler = new StdSchedulerFactory().getScheduler();
        scheduler.start();
        scheduler.scheduleJob(job, trigger);

        //
        latch.await();

        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    scheduler.shutdown();
                    latch.countDown();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }));

    }






}

和工作班将是

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class SimpleJob implements Job {


    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("executing task!");
    }


}

我会为此创建一个可执行jar并使用java -jar .. &启动它,Ctrl+C可以停止该过程,如果你想在后台disown启用它

答案 4 :(得分:0)

This page有一个使用TimerTimerTask的好例子,您可以根据自己的需要进行微调。

答案 5 :(得分:0)

以下代码将在18:20运行,它将以5秒的间隔重复。

while (!threadStatus.isStopped()) {
      threadStatus.checkForPause();   

     // do your processing here
}