プログラム悪戦苦闘日記

はてなダイアリーからの移行(遺物)

System.currentTimeMillis()の罠に堕(お)ちる

 のんきに描画APIを調べている場合ではないようだ。
System.currentTimeMillis()はミリ秒をlong値で返すので、分解能は1msecだと思っていたら、

public static long currentTimeMillis()

現在の時間をミリ秒で返します。
戻り値の時間単位はミリ秒ですが、値の粒度は基本となるオペレーティングシステムによって異なり、
単位がより大きくなる場合があります。
たとえば、多くのオペレーティングシステムでは、時間を 10 ミリ秒の単位で計測します。

JavaDoc JDK1.4.0より

Windowsもマルチメディアタイマーを使っていれば、分解能は1msec程度はあるので、
とうぜんJDKはこのAPIを呼び出す仕様になっていると思っていたんだが、
実際には戻り値は10づつしか更新されないらしい。調べてみよう。
 単純に、次のように、currentTimeMillis()の値を出力してみると、

public class Test1 {
    public static void main(String[] args) {
        for(int i=0; i<100; ++i)
            System.out.println("" + System.currentTimeMillis());
    }
}

結果は、

1095318072764
1095318072774
1095318072774
1095318072774
1095318072774
1095318072774
1095318072784
1095318072784
1095318072784
1095318072784
1095318072794
1095318072794
1095318072794
1095318072794
1095318072794
1095318072804
1095318072804
1095318072804
1095318072804
1095318072814
1095318072814
1095318072814
1095318072814
1095318072814
1095318072824
1095318072824
1095318072824
1095318072824
1095318072824
:

となり、10ずつしか更新されていない。つまり、System.currentTimeMills()の分解能は10msecということだ。
これでは全く使い物にならない!
 仕方が無いので代替手段が必要だ。Javaで時間やタイマーに関係あるAPIは、すぐに思いつくところで、

  1. System.currentTimeMillis()
  2. Thread#sleep()
  3. java.util.Timer
  4. javax.swing.Timer

の4つか。これらの分解能を調べれなければならないのだが、それにはもっと分解能の高いタイマーが必要で、
JavaAPIに頼れないから、Windows APIを使うしかない。つまり、JNIを使うのだ。
 
 そういう訳で結果は後日。めんどくさいなー。