9

1秒間にいくつかの命令または関数をN回実行しようとしています。Javaでこれを行うにはどうすればよいですか? 次のように...

//in one second
while(N)
{
  printf(".........");
  int x=0;
  printf("The value of x is ");
}

しかし、質問は実際にはもう少し深くなります..ピクセルを手動でプロットしようとしていますが、1秒あたりの回転数が必要ないため、基本的には1秒間にN回実行する必要があります(ただし、これは無限に行われます)

前もって感謝します

4

7 に答える 7

6

1秒間に正確にN回発生するかどうかはわかりませんが、次のようになります。

long taskTime = 0;
long sleepTime = 1000/N;
while (true) {
  taskTime = System.currentTimeMillis();
  //do something
  taskTime = System.currentTimeMillis()-taskTime;
  if (sleepTime-taskTime > 0 ) {
    Thread.sleep(sleepTime-taskTime);
  }
}
于 2013-02-07T07:45:12.423 に答える
5

問題を裏返します。ループを1秒間にN回に制限しないでください。代わりに、N個の作業単位を目的の時間に均等に分散して処理します。

つまり、開始(または前の作業)から経過した時間を計算し、それを作業率に補間して、その量の作業を実行します(開始/前の時間と実行された作業の量を考慮に入れます)。これは、多くのゲーム/アニメーションエンジンの基本的な基盤である「デルタタイム」です。

次にyield、各ループの最後で「良くなる」ように呼び出します。つまり、99%以上のCPU使用率を消費しないようにします。歩留まり自体の分解能は最小1ですが、特に適切に補間する場合、効果は一般的に適切です。

補間アプローチが使用されるため、これは、ループごとにさらに多くのNを実行することを意味する場合でも、すべてのN(割り当てられた時間内に実行可能)で機能するはずです。小さなNに対して特定のループで作業が行われない可能性もありますが、yieldこの種の「非常にビジーなループ」はCPU使用率の点で安価になります2


これは、1秒間に20個の「x」を出力するための擬似コードです。ここで、now秒の小数部が返されます。

rate = 20       // per second - "N times per second"
done = 0
goal = 1 * rate // same as rate for 1 second
start = now()
while done < goal:
    target = floor((now() - start) * rate)
    work = (target - done) // work might be 0, that's okay
    for 0 upto work:
         print("x")
    done += work
    yield()

この場合、定率式のため、開始時刻から簡単に補間できます。最後の作業(またはループ)からの時間に基づく「デルタ時間」の使用は類似しており、離散式がない場合に適していますが、少し複雑で、微妙なドリフトエラーが発生する可能性があります。


1実際 の時間分解能sleep/yieldは実装に依存し、システムによって異なります。たとえば、Linuxの場合は1ミリ秒、Windowsの場合は10〜15ミリ秒の範囲である可能性があります。

2タイムデルタを処理することに加えてsleep、Dariusz Wawerの回答に従って、期間を変更できます。ただし、これにより複雑さが増し、yield多くの場合、単純なもので十分です。

于 2013-02-07T07:54:21.057 に答える
1

今日はゲームループを書かなければなりませんでした。前のティックが速すぎた場合に次のティックが長く待機するようにするオーバーフロー変数を使用しました。ティックごとにオーバーフローの半分が削除され、フレームタイムに影響を与えるために使用されます。

new Thread() {
        public void run() {
            long overflow = 0; // The greater the overflow, the slower the game had calculated the last tick, and the shorter this tick's wait needs to be
            long lastStartTime = System.nanoTime();
            while(true) {
                long startTime = System.nanoTime();
                overflow += (startTime - lastStartTime) - 16666667; // 16.67 milliseconds = 60 fps

                tick();

                long endTime = System.nanoTime();
                long waitTime = 16666667 - (endTime - startTime) - overflow / 2;
                try {
                    Thread.sleep(waitTime / 1000000, (int) (waitTime % 1000000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                overflow /= 2; // Do not remove all overflow at once to prevent oscillation of ticktime
                lastStartTime = startTime;
            }
        }
    }.start();
于 2018-12-24T03:22:45.073 に答える
0

疑似コード:

Create Timer t;
t.Start;
int counter = N;
While ((t.Elapsedtime < 1 Second) AND (N > 0))
{
    call your_function();
    N--;
}

your_function()
{
    printf(".........");
    int x=0;
    printf("The value of x is ");
}
于 2013-02-07T07:48:19.503 に答える
0

ループを に変更しますwhile(true)

whileループの前にミリ秒単位で時間を確認してください。ループの最後でwhileミリ秒単位の時間を取得し、1000 回経過したかどうかを確認します。もしそうならbreak

于 2013-02-07T07:45:57.163 に答える
0
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start <= 1000) {
  // Your code goes here
}

コードが 1000 ミリ秒間ループされるだけです。実行される回数は不確実であり、実行ごとに異なる場合があります。

于 2013-02-07T07:49:20.203 に答える