简体   繁体   English

仅在当前时间每秒执行一次代码?

[英]Execute code every second with only the current time?

How can i execute code every second when only using the current time? 仅使用当前时间,我如何每秒执行代码? ( no extra variables , it doesn't have the be exactly every second, I'm quite happy with a variation between 800 to 1200 ms) 没有额外的变量 ,它没有精确到每秒,我对800到1200 ms之间的变化感到非常满意)

I did try: 我确实尝试过:

//code repeated every 30-100ms
if ((System.currentTimeMillis() % 1000) == 0) { //execute code

But this doesn't work, cause the chance that currentTimeMillis can be exactly divided by 1000 is not very high. 但这不起作用,导致currentTimeMillis可以精确地除以1000的机会不是很高。

Any bright ideas on the subject? 关于这个主题有什么好主意吗?

[edit] please note my "no extra variables" remark. [edit]请注意我的“没有多余的变量”备注。 Let me explain a bit better: i need to put this code in a place where i only have a long value indicating the unix time since 1970 (the value of currentTimeMillis). 让我更好地解释一下:我需要将这段代码放在一个只有一个长值(表示1970年以来的Unix时间)的位置(currentTimeMillis的值)。 I can't remember anything, nor can i save extra variables that can be accessed the next time my code is executed. 我什么也记不清,也无法保存下次执行代码时可以访问的额外变量。 It's a special case. 这是特例。

The best way to do this is to use ScheduledExecutorService 最好的方法是使用ScheduledExecutorService

ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
Future future = service.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.SECONDS);

When you no longer need it, you can cancel execution 当您不再需要它时,可以取消执行

future.cancel(true);
while(true) {
  //execute your code here
  Thread.sleep(1000);
}

The only way I can think of to do this would be to check that we are in the time window, perform the action and then use Thread.sleep long enough to ensure we are out of the time window. 我能想到的唯一方法是检查我们是否在时间范围内,执行操作,然后使用Thread.sleep足够长的时间以确保我们不在时间范围内。

private static final long WINDOW = 200;

void doItOncePerSecond(long time) throws InterruptedException {
    // Check the time.
    if ((time % 1000) / WINDOW == 0) {
        // Do your work.
        System.out.println("Now!! " + time + " - " + (time % 1000));
        // Wait long enopugh to be out of the window.
        Thread.sleep(WINDOW - (time % 1000));
    }
}

public void test() throws InterruptedException {
    System.out.println("Hello");
    long start = System.currentTimeMillis();
    long t;
    while ((t = System.currentTimeMillis()) - start < 10000) {
        doItOncePerSecond(t);
        Thread.sleep(100);
    }
}

Beyond that you may need to persist a value in some other way - perhaps use a socket to yourself. 除此之外,您可能还需要以其他方式保留值-也许对自己使用套接字。

This if statement would do it as per you request (between 800ms and 1200ms) but it is very inefficient and my previous answer or some of the other answers would be a lot better at doing what you want 这个if语句可以按照您的要求(在800毫秒至1200毫秒之间)执行此操作,但是效率很低,我以前的回答或其他一些回答会更好地完成您想要的操作

if ((System.currentTimeMillis() % 1000) < 200 || (System.currentTimeMillis() % 1000) > 800) {

}

or since you code is repeated roughly every 30-100 ms you can use 或者由于您的编码大约每30-100毫秒重复一次,因此您可以使用

if ((System.currentTimeMillis() % 1000) < 100|| (System.currentTimeMillis() % 1000) > 900) {

}

You can use java.util.Timer for this, but you can't do this scheduled operation without defining extra variable or it will be in infinity mode. 您可以为此使用java.util.Timer,但是如果不定义额外的变量就无法执行此计划的操作,否则它将处于无限模式。

You can try this: 您可以尝试以下方法:

new Timer().schedule(task, delay, period);

You can try this to get seconds and use it the way you would like to ... 您可以尝试此操作以获取秒数并以您希望的方式使用它。

long timeMillis = System.currentTimeMillis();
long timeSeconds = TimeUnit.MILLISECONDS.toSeconds(timeMillis);

This does something every 1 second 每1秒钟执行一次操作

while (true) {
    System.out.println("a second has passed");
    Thread.sleep(1000);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM