Java 如何使用Timer类来调用一个方法、执行某些操作、重置计时器、重复?

Java 如何使用Timer类来调用一个方法、执行某些操作、重置计时器、重复?,java,timer,scheduled-tasks,Java,Timer,Scheduled Tasks,我是一名Java初学者,一直在研究解决这个问题的各种解决方案,我有点纠结。我尝试了线程,然后发现了这个计时器类,但到目前为止还没有成功。如果你能用一个main方法发布可执行代码,这样我就能看到它在工作,并从那里开始玩,那就太好了 发射计划 调用doSomething() 生成随机数,并为该时间设置计时器 计时器关闭时,再次调用doSomething() 可能是这样的:您特别想要一个计时器吗?如果不是这样,您最好使用和调用scheduleAtFixedRate或scheduleWithFixedD

我是一名Java初学者,一直在研究解决这个问题的各种解决方案,我有点纠结。我尝试了线程,然后发现了这个计时器类,但到目前为止还没有成功。如果你能用一个main方法发布可执行代码,这样我就能看到它在工作,并从那里开始玩,那就太好了

  • 发射计划
  • 调用
    doSomething()
  • 生成随机数,并为该时间设置计时器
  • 计时器关闭时,再次调用
    doSomething()

  • 可能是这样的:

    您特别想要一个
    计时器吗?如果不是这样,您最好使用和调用
    scheduleAtFixedRate
    scheduleWithFixedDelay
    ;引述:

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

    更新

    下面是一些使用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
    

    如果您想简单地使用计时器,我会这样做:

    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
        }
    }
    
    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);
                }
            };
        }
    }
    
    对不起,你的身份很糟糕

    另外,如果您需要计划代码的执行,请看一看,因为它确实可以使您的代码更加清晰,并抽象出相当多的创建线程、计划等样板文件

    顺便说一句,我没有费心去生成随机数,但我想你可以想出如何包含这一部分。我希望这足以让你走上正轨

    记录在案,如果你使用番石榴,它看起来会像这样:

    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
        }
    }
    
    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;就是这样。

    想象一个场景,在这个场景中,我希望代码在应用程序中的某个特定时间执行,或者在当前时间之后的某个时间执行。换句话说,我想把我的任务安排在确定的时间

    类(java.util.Timer)允许应用程序在单独的后台线程上调度任务

    以下是最简单的:


    分析: 对timer.schedule(task,100001000)的调用将计划在调用10秒后第一次执行(在另一个线程上)的任务。之后,它将在延迟10秒后再次调用。这里需要指出的是,如果任务在10秒后无法启动,则下一个任务调用将不会得到pre-pond。所以这里两个连续任务之间的延迟时间是固定的


    来源:

    如果您不想使用timer类,并且可以使用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
    it

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

    public static void main(String[] args) {
        Timer timer = new Timer();
        TimerTask tt = new TimerTask() {
            public void run() {
                Calendar cal = Calendar.getInstance();
    
                int hour = cal.get(Calendar.HOUR_OF_DAY);
                int min = cal.get(Calendar.MINUTE);
                if (hour == 18 && min == 20) {
                    doSomething();
                }
            }
        };
        timer.schedule(tt, 1000, 5000);
    }
    

    不要用定时器来做这件事。使用java.util.concurrent中的内容。它更容易理解,性能更高,更健壮。下面的SimonC示例是一个不错的方法。