-1

我正在尝试为我的循环添加延迟。它不能是 thread.sleep() 因为它会使整个线程休眠。我正在尝试使用System.currentTimeMillis(). 我知道这不是 100% 精确的,这很好。

long lastTime = System.currentTimeMillis() - 200;
boolean goAhead = false;

if (System.currentTimeMillis() - lastTime > 201) { 
    goAhead = true; 
}

if (goAhead) {
    //Do something
    //atm this never happens. 
    lastTime = System.currentTimeMillis();
}

有人能帮忙吗?

4

4 回答 4

3

为什么“睡眠整个线程”是一个问题?无论如何,如果您想忙于等待,请while循环执行。if是一枪。

于 2012-09-15T11:13:22.727 回答
2

这就是我想象的问题可能是:

问:我在 GUI 事件线程上有一个回调,它必须每 250 毫秒在同一线程上触发一次操作。我不能在这段时间内阻止 GUI 线程,因为它冻结了 GUI。我能做些什么?

A:使用执行器在 GUI 事件线程上定期触发任务。

Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                // task to be perform periodically in the GUI Event Thread.
            }
        });
    }
}, 250, 250, TimeUnit.MILLISECONDS);

执行任务的 GUI 线程,但执行等待的后台线程。


我会写一些更像

long time = 0;
while(condition) {
   long now = System.nanoTime();
   if (now >= time + 200e6) {
      // do something
      time = now;
   }
   // do something else
}

在不知道程序的具体要求的情况下,可以将代码读取为。

long time = 0; // a local variable or field as appropriate

// you have a loop around all code of interest at some level
// You could have a GUI event loop which you don't define but it is there.

// at some point your checking code is called.
   long now = System.nanoTime();
   if (now >= time + 200e6) {
      // do something
      time = now;
   }

这不会等待,因为您不想阻止任何事情。相反,它可以防止代码块的调用间隔小于 200 毫秒。


int i = 0, count = 0;
long start = System.nanoTime();

long time = 0;
while (count < 20) {
    long now = System.nanoTime();
    if (now >= time + 200e6) {
        // do something e.g.
        count++;

        time = now;
    }
    // do something else
}
long runTime = System.nanoTime() - start;
System.out.printf("Performed something at %.3f per second%n", (count - 1) * 1e9 / runTime);

印刷

Performed something at 5.000 per second
于 2012-09-15T11:12:47.520 回答
2

它不起作用的原因是

if (System.currentTimeMillis() -lastTime > 201) { goAhead= true; } 

执行一次,就是这样,你需要把它放到一个循环中,例如

while (System.currentTimeMillis() -lastTime < 201) {
// wait
}

但是它会给你大约。100% 的 CPU 使用率毫无意义,我相信这是一个糟糕的设计

于 2012-09-15T11:13:32.133 回答
0

到目前为止,最好的等待方式是使用Thread.sleep()(或Object.wait()超时);它阻塞了线程,但它以可预测的方式这样做。如果您绝对必须在等待时做一些事情,请将睡眠其他工作放在单独的线程中,并使用线程间协调原语来同步事情。

final Thread mainthread = Thread.currentThread();
Thread t = new Thread() {
    public void run() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {}
        mainthread.interrupt();
    }
}.start();

while (!Thread.interrupted()) {
    // Do your other work here...
}

Java中的线程(相对)便宜。使用它们。

于 2012-09-15T11:28:02.073 回答