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は、すぐに思いつくところで、
- System.currentTimeMillis()
- Thread#sleep()
- java.util.Timer
- javax.swing.Timer
の4つか。これらの分解能を調べれなければならないのだが、それにはもっと分解能の高いタイマーが必要で、
JavaのAPIに頼れないから、Windows APIを使うしかない。つまり、JNIを使うのだ。
そういう訳で結果は後日。めんどくさいなー。