もうひとつは、(株)アルファシステムズの岡田さんが Kafka のメイリングリストでアナウンス (kafka-user:29) されたページ 「各社エージェントの機能比較」 です。 このページでは、各社の移動エージェント記述ライブラリ ( Voyager, Aglets Workbench, Odyssey, Kafka ) が比較されています。
各ライブラリの API を見てびっくり、移動先では、システム またはユーザが指定したメソッドが呼び出されるだけです。 例えば Voyager での移動の記述はこんな感じです。
Aglets Workbench では、移動後に callback メソッドmoveTo(移動先, String メソッド名, Object 引数)
が呼び出されるようです。public void onArrival()
つまらな過ぎる!実行コンテクストは捨てるのか? プログラミングインタフェースとして透過性が低くて醜い!
ということで、スレッドが移動できれば、移動エージェントも 通常の移動しないプログラムとほぼ同じ作法で記述できるな、 と思い立ちました。
JDK 1.1 より、 Reflection の API が提供されるなど、自己反映的な操作を行いやすくはなりました。 それでもまだ、スレッド移送を実現するためには、C言語を使っ て JVM を拡張する必要があります。つまり、native methods を書く必要があります。
native methods を使えば何でもできますが、反面、様々なデ メリットがあります。Java でのソフトウェア開発で、native methods を使用することのデメリットは許容されないことが多 いです。
native methods を使用することで、 次のように、Java の利点がある程度損なわれます。
native methods を使用することで得られるものと失うものが 秤にかけられます。移動エージェント記述ライブラリを開発し ている各社にとって、失うものの方が大きかったのでしょう。 理解できます。
私は、native methods を利用しても何でもいいから スレッド移送を実現したいと思いました。
高速化のために native methods を使う場合は、はなから C や C++ で書くことも含めて慎重に検討すべきです。Java 部分 が C の wrapper にならないように…
native methods は C で記述するわけですが、Java のメソッ ドを書く以上、当然 GC を考慮しなければなりません。C 側で まだ使いたいオブジェクトが GC で回収されていた、なんてこ とも経験しました。
profiling については状況は絶望的です。native methods を Java の profiling 対応に書き換えましたが、C の関数と Java のメソッドが呼び合う状況ではまだ動作がおかしいです。 C のレベルで profiling することが考えられますが、このためには JDK を自分でコンパイルする必要があります。これにはまだ挑戦していません。
multithreading (以下 MT) 関係でもいろいろと悩まされまし た。native methods 中で、MT と相性の悪い signal をどうし ても利用する必要があり面倒だったり、 これまた MT safety と相性の悪い setjmp(), longjmp() が 必要で困ったり…
MT と言えば、デバッグ時、非同期 GC にもずいぶん混乱させられました。