-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

これは、質問が次のようになると私が想像する方法です。

Q: 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
}

ただし、それはあなたにcaを与えます。何もないのに 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 に答える