Java 如果一个方法本身需要一些时间,我们如何仍然每X秒运行一个方法?
如果某个方法本身的运行时间少于x秒,我可以知道计划该方法每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");
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");
}
}