@Tagir_Valeev
と言っても、あなたのウィンドウのスケジューラはそれほど良くはありません。これは私が推測する主な理由の1つです。
もう1つの理由は、2つの時点の間にlogger.info()
があることです。おそらく数ミリ秒かかることがあります。
したがって、プログラムを次のように記述すると、より正確になる可能性があります。
SleepAccuracyTest.java:(TestNG
クラス、ロガーとしてSlf4j
を使用)
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
// test sleep accuracy,
public class SleepAccuracyTest {
public static final int MAX_DIFF = 1; // max diff in milliseconds,
private Logger logger = LoggerFactory.getLogger(SleepAccuracyTest.class);
private int counter = 0;
@Test(invocationCount = 10, alwaysRun = true)
public void testIt() {
int during = 1000;
counter++;
try {
logger.info("Started [{}]", counter);
logger.info("No Arguments passed waiting for {} milliseconds...", during);
long start = System.currentTimeMillis();
Thread.sleep(during);
long end = System.currentTimeMillis();
long actualDuring = end - start;
long diff = actualDuring - during;
Assert.assertTrue(Math.abs(diff) <= MAX_DIFF);
logger.info("Expected during: {}, actual duration: {}, diff: {}", during, actualDuring, diff);
logger.info("Ended\n");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
試験結果:私のマシン(64ビットのLinux 3.16で
、Java8、 4 cpu):
- コードを実行すると、1〜6ミリ秒の差分があります。
- 上記のコードを実行すると、ほとんどの場合0の差分がありますが、時には1ミリ秒の差があります(1ミリ秒は単なる丸めです)。
したがって、logger.info()
またはSystem.out.printf()
にも時間がかかります。 数ミリ秒に過ぎず、わずか数ミリ秒です。
私はこれを私のMACでシミュレートしようとしましたが、期待される答えを見ています。私は私のMac OSでそれをやった –
もう一度それを試すことができますか?いつも「55」ですか? –
必ずしも異なるとは限りません。しばらくそれは一致します。 Thread.sleepがより正確であることを理解したかっただけです。 –