S2Chronosでいろいろやる
ちょっといろいろ作ってみているが、
なんか不可思議な現象が。
SscheduleにaddTaskとremoveTaskがあるけど、
実際に中のほうで持っているのは、
Sschedule#TaskScheduleEntryManager#taskScheduleEntryClassMap
こいつかタスクを管理している(?)。
んで、こいつの型が、
ConcurrentHashMap<Class<?>, TaskScheduleEntry>
ConcurrentHashMapってチョー厳密なハッシュマップ(w)だから、
型であっても、インスタンスが違ったら不一致になる。
型変数とか見よう見まねでしか勉強をしたことがない、
実際にJVM的にどうなるのかよくわかってないのだが、
あるときに生成したClass型のインスタンス(?)
と
別のときに生成したClass型のインスタンス(?)
って、
別のインスタンスになるから、
ConcurrentHashMapじゃとってこれない気がするんだけど、
なので、
Schedule#addTaskしたものが、
Schedule#removeTaskでからぶる。
- 検証
検証シチュエーション:
既にスケジュールが動いている状態
検証コード:
TaskScheduleEntryManager value = TaskScheduleEntryManager.getInstance(); Field f2 = ReflectionUtil.getDeclaredField( value.getClass(), "taskScheduleEntryClassMap" ); f2.setAccessible( true ); ConcurrentHashMap<Class<?>, TaskScheduleEntry> taskScheduleEntryClassMap = (ConcurrentHashMap<Class<?>, TaskScheduleEntry>)ReflectionUtil.getValue( f2, value ); Method m = ReflectionUtil.getDeclaredMethod( ConcurrentHashMap.class, "hash", int.class ); m.setAccessible( true ); for ( Map.Entry<Class<?>, TaskScheduleEntry> ent : taskScheduleEntryClassMap.entrySet() ) { Object key = ent.getKey(); int hash = (Integer)ReflectionUtil.invokeStatic( m, key.hashCode() ); logger.debug( key+"="+hash ); } int hash = (Integer)ReflectionUtil.invokeStatic( m, clazz.hashCode() ); logger.debug( clazz+"="+hash );
結果:
DEBUG 2010-11-24 16:11:29,715 [http-80-1] class rootpackage.task.OneMinuteTask=1103040895 DEBUG 2010-11-24 16:11:29,715 [http-80-1] class rootpackage.task.Class20101124154520Task=138201009 DEBUG 2010-11-24 16:11:29,715 [http-80-1] class rootpackage.task.Class20101124154520Task=1567105810
同じ型なのに、ConcurrentHashMapのgetするキー?が違うんだよね。
うーん?俺のアプローチの仕方が違うのかな。
addTaskもremoveTaskも引数がClassだから、
これでいいと思うんだけど…。
と思ったんだけど、
Tomcatを落としあげてもう一回やってみると合う…、?????
というか、
ConcurrentHashMapのキーが同じになって、
removeTaskが正常に動作することもある。
ConcurrentHashMapのキーが違う値になって、
removeTaskが正常に動作しない場合もある。
えーwなにこれーw
なんかわかった気がするが、
今はまとめる気にならないので、
いつかまとめる。
ConcurrentHashMap的にhashが違うのは、
本当にClassのインスタンスが違ったのだ。
そりゃー違うわねw
型は同じなのにインスタンスが違うという、
クラスローダー的な話だが、その辺はあまり考えたくないw
結論的には多分S2ChronosもConccurentHashMapも悪くない。
俺のアイディア?かロジック?がぶっ飛んでいたようだw