[英]How do we still run a method every X seconds if the method itself takes some time?
如果方法本身需要一定的時間(少於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);
}
}
我如何保證在0s之后第二次調度函數是1s(無延遲)而不是1.1s?
要在上一個任務結束后的毫秒數開始任務,可以使用ScheduledExecutorService
:
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");
}
}
像這樣更改代碼:
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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.