Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如果一个方法本身需要一些时间,我们如何仍然每X秒运行一个方法?_Java_Timer - Fatal编程技术网

Java 如果一个方法本身需要一些时间,我们如何仍然每X秒运行一个方法?

Java 如果一个方法本身需要一些时间,我们如何仍然每X秒运行一个方法?,java,timer,Java,Timer,如果某个方法本身的运行时间少于x秒,我可以知道计划该方法每x秒运行一次的最佳方法是什么吗 例如: import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.TimeUnit; class Helper extends TimerTask { public void run() { System.out.println("Start");

如果某个方法本身的运行时间少于x秒,我可以知道计划该方法每x秒运行一次的最佳方法是什么吗

例如:

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

class Helper extends TimerTask 
{ 
    public void run() 
    { 
        System.out.println("Start");
        //for example, the program takes about 100 ms to run and the exact time may vary
        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("End");

    } 
} 

public class Test 
{ 
    public static void main(String[] args) 
    { 

        Timer timer = new Timer(); 
        TimerTask task = new Helper();
        timer.schedule(task, 0, 1000); 

    } 
}

我如何保证在0秒后,函数的第二次调度时间是1秒,没有延迟,而不是1.1秒?

如下更改代码:

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

class Helper extends TimerTask 
{ 
    public void run() 
    { 
        long current = System.currentTimeMillis();
        System.out.println("Start");
        //for example, the program takes about 100 ms to run and the exact time may vary
        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("End");
        long after = System.currentTimeMillis();
        Timer timer = new Timer(); 
        TimerTask task = new Helper();
        timer.schedule(task, 0, 1000 - (after - current)); 

    } 
} 

public class Test 
{ 
    public static void main(String[] args) 
    { 

        Timer timer = new Timer(); 
        TimerTask task = new Helper();
        timer.schedule(task, 0, 1000); 
    } 
}
另一个选项是使用thread.sleep:

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

class Helper extends TimerTask 
{ 
    public void run() 
    { 
        while(true)
        {
            long current = System.currentTimeMillis();
            System.out.println("Start");
            //for example, the program takes about 100 ms to run and the exact time may vary
            try {
                TimeUnit.MILLISECONDS.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("End");
            long after = System.currentTimeMillis();
            Thread.sleep(1000 - (after - current)); 
        }

    } 
} 

public class Test 
{ 
    public static void main(String[] args) 
    { 

        Timer timer = new Timer(); 
        TimerTask task = new Helper();
        timer.schedule(task, 0, 1000); 
    } 
}

要在上一个任务结束后x毫秒启动任务,可以使用ScheduledExecutorService:


使用quartz SchedulerTanks。但这并不理想,因为它会以指数方式创建额外的任务实例。@jsh6303创建新实例有什么错?每次任务结束时,最后一个实例将转到垃圾收集器,因此每次只有一个活动实例。你不能从外部任务中调用任务,因为你知道它所花费时间的唯一地方是它本身。并检查更新。
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Test
{
    public static void main(String[] args)
    {
        ScheduledExecutorService seService = Executors.newSingleThreadScheduledExecutor();
        Runnable task = new Helper(seService);
        seService.execute(task);
    }
}

class Helper implements Runnable
{
    private final ScheduledExecutorService seService;

    Helper(ScheduledExecutorService seService) {
        this.seService = seService;
    }
    @Override
    public void run()
    {
        System.out.println("Start");

        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {     e.printStackTrace();  }

        seService.schedule(this, 1000, TimeUnit.MILLISECONDS); //execute again after delay
        System.out.println("End");
    }
}