java—每隔一段时间调用一个函数

java—每隔一段时间调用一个函数,java,Java,我有一个程序,可以在其中插入一个文件路径及其对应的参数到一个表中 之后,我有另一个函数,名为do\u Scan() 它扫描表并对其进行一些处理和索引 但是,我希望这个函数do_Scan()以一定的间隔运行,比如说每N分钟运行一次,然后它就会调用这个函数。N是绝对可配置的 我正在考虑使用计时器类,但不太确定如何实现配置。我的想法是创建一个计时器函数,它将调用do\u Scan方法 课程应该是这样的: public void schedule(TimerTask task,long delay,lo

我有一个程序,可以在其中插入一个文件路径及其对应的参数到一个表中

之后,我有另一个函数,名为
do\u Scan()
它扫描表并对其进行一些处理和索引

但是,我希望这个函数
do_Scan()
以一定的间隔运行,比如说每N分钟运行一次,然后它就会调用这个函数。N是绝对可配置的

我正在考虑使用计时器类,但不太确定如何实现配置。我的想法是创建一个计时器函数,它将调用
do\u Scan
方法

课程应该是这样的:

public void schedule(TimerTask task,long delay,long period){

}
我的主要方法是:

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

    Indexing test= new Indexing();
    java.sql.Timestamp date = new java.sql.Timestamp(new java.util.Date().getTime());
    // Exception e=e.printStackTrace();
    Scanner scanner = new Scanner(System.in);
    System.out.print("Enter a file path: ");
    System.out.flush();
    String filename = scanner.nextLine();
    File file = new File(filename);
    if(file.exists() && !file.isDirectory()) {
        test.index_request(filename,"Active",date,date,"");
    }else{
        test.index_request(filename,"Error",date,date,"Some errorCode");
    }

    // Call schedule() function 
}}

如何设置Timer类,使其无限期地运行一定的时间间隔?

为此,我建议您使用Java的
ScheduledExecutorService
,它为您提供了一个API,可以按固定速率(以及其他API)调度任务

您有两个选项可以执行此操作:

  • 在任务中实现
    Runnable
    Callable
    (或类似)并调用
    schedule()
    方法:

    public class IndexingTask implements Runnable {
    
        @Override
        public void run() {
            schedule();
        }
    
        private void schedule() {
            //do something
        }
    }
    
    
    
    public static void main(String[] args) {
        //do some stuff
        long delay = getDelay();
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
        scheduledThreadPool.scheduleAtFixedRate(new IndexingTask(), 0, delay, TimeUnit.SECONDS);
    }
    
  • 使用Lambda表达式内联执行此操作:

    public static void main(String[] args) {
        //do some stuff
        long delay = getDelay();
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
        scheduledThreadPool.scheduleAtFixedRate(() -> doSomething(), 0, delay, TimeUnit.SECONDS);
    }
    
  • 如果您使用的是Spring Framework,只需使用
    @Scheduled
    注释,如下所示:

    @Scheduled(fixedRate = 5000)
    public void schedule() {
        //do something
    }
    

    有很多方法可以解决这个问题。我认为最简单的方法是,当您仅在给定位置使用此方法,而不使用Spring之类的外部框架时:

    private void runWithInterval(long millis) {
        Runnable task = () -> {
            try {
                while (true) {
                    Thread.sleep(millis);
                    // payload
                }
            } catch(InterruptedException e) {
            }
        };
    
        Thread thread = new Thread(task);
        thread.setDaemon(true);
        thread.start();
    }
    
    要以1分钟的间隔调用它,请执行以下操作:

    runWithInterval(时间单位:分钟:1)

    p.S.

    您可以在此处的其他帖子中看到其他方式的详细信息:

    • @Scheduler
      使用
      Spring时的注释
    • 将线程池与单线程一起使用:
      ScheduledExecutorService scheduledThreadPool=Executors.newFixedThreadPool(1)
    • 使用
      Timer
      new Timer().schedule(new Runnable(){},TimeUnit.MINUTES.toMillis(1))

      • 最简单的方法是使用标准库中的类

        java.util.Timer
        
        下面是一个使用它的简单示例:

        import java.util.Timer; 
        import java.util.TimerTask; 
        
        class MyTask extends TimerTask 
        { 
           public static int i = 0; 
           public void run() 
           { 
              System.out.println("Hello, I'm timer, running iteration: " + ++i); 
           } 
        } 
        
        public class Test 
        { 
           public static void main(String[] args) 
           { 
        
              Timer timer = new Timer(); 
              TimerTask task = new MyTask(); 
        
              timer.schedule(task, 2000, 5000);  // 2000 - delay (can set to 0 for immediate execution), 5000 is a frequency.
        
           } 
        } 
        
        如果您熟悉java库,可以将其用作:

        Flowable.interval(1, TimeUnit.SECONDS) // Or any other desired interval
                .subscribe(iteration -> System.out.println("Hello, I'm timer, running iteration: " + iteration));
        

        但您确实应该阅读更多有关此方法和库的信息

        您可以通过使用
        ScheduledThreadPoolExecutor
        实现这一点:

        假设您有一个任务方法:

        public void task(String foo, Integer bar){
            // ...
        }
        
        在Java 1.8之前

        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2);
        executor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                task(fooParam, barParam);  
            }
        }, 0, 60, TimeUnit.SECONDS);
        
        Java1.8+

        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
        executor.scheduleAtFixedRate(() -> task(fooParam, barParam), 0, 60, TimeUnit.SECONDS);
        

        例子?但是我想让计时器发挥它自己的功能,看看这是否对你有帮助是的,确实有帮助。这是实现这一目标的最佳方式吗?建议
        Runnable
        的答案相当古老。改用lambdas(从java 1.8开始)。如果其中出现任何错误,那么我需要编写另一个函数来处理它。是的,当然,但这是您的自定义逻辑,取决于应用程序。计时器只提供周期性运行某些内容的功能。这并不能避免处理错误。这种方法会导致漂移,因为有效载荷会影响计时。