Как использовать класс Timer для вызова метода, что-то сделать, сбросить таймер, повторить? - PullRequest
28 голосов
/ 23 февраля 2012

Я новичок в Java, и я раздумывала над различными решениями этой проблемы, и у меня возникли проблемы.Я попробовал с Threads, а затем обнаружил этот класс Timer и до сих пор безуспешно с ним боролся.Если бы вы могли опубликовать исполняемый код с основным методом , чтобы я мог видеть, как он работает, и начать оттуда играть, это было бы здорово.

  1. Запустите программу
  2. call doSomething()
  3. Генерация случайного числа и установка таймера на это время.
  4. Когда таймер отключается, снова позвоните doSomething().

Возможно, с помощью этого: http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html

Ответы [ 6 ]

41 голосов
/ 23 февраля 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
    }
}

Извините за паршивую подделку.

Кроме того, если вам нужно запланировать выполнение кода, взгляните на Службы Guava , так как это действительно может сделать ваш код намного более четким и абстрагировать немало шаблонной схемы создания потоков, планирования и т. Д. .

Кстати, я не взялся за генерацию случайных чисел и т. Д., Но я думаю, что вы можете выяснить, как включить эту часть. Надеюсь, этого достаточно, чтобы вы встали на правильный путь.

Для справки, если бы вы использовали 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);
            }
        };
    }
}

И вы просто создадите main, который называется new CrawlingService.start (); это все.

25 голосов
/ 23 февраля 2012

Вы специально хотите Timer?Если нет, то вам, вероятно, лучше воспользоваться ScheduledExecutorService и вызовом scheduleAtFixedRate или scheduleWithFixedDelay;цитируя 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
3 голосов
/ 05 апреля 2016

Подумайте о сценарии, в котором я хочу, чтобы мой код выполнялся в определенное время в моем приложении или спустя некоторое время после текущего времени. Другими словами, я хочу запланировать свою задачу на определенное время.

Java Timer * Класс 1004 * (java.util.Timer) позволяет приложению планировать задачу в отдельном фоновом потоке.

Вот самый простой пример 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 (task, 10000,1000) запланирует задачу, которая будет выполнена впервые (в другом потоке) через 10 секунд после этого вызова. После этого он позвонит снова с задержкой в ​​10 секунд. Здесь важно отметить, что если задача не может быть запущена через 10 секунд, следующий вызов задачи не получит предварительный пруд. Так что здесь время задержки между двумя последовательными заданиями фиксировано.

Источник: Пример таймера Java

1 голос
/ 28 марта 2017

Если вы не хотите использовать класс таймера и можете использовать 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 это

0 голосов
/ 24 мая 2018

Приведенный ниже код будет запущен в 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);
}
0 голосов
/ 23 февраля 2012

На этой странице есть хороший пример использования Timer s и TimerTask s, которые вы можете точно настроить для своих нужд.

...