- - PR -
ThreadLocalの利用について
| 投稿者 | 投稿内容 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-09-17 12:55
お世話になります。 非常にアバウトな質問で申し訳ありませんが、ThreadLocalの 有用性について、情報を頂ければと思います。 ThreadLocalは非常に便利なクラスだと思っているのですが、 私自身は簡単なアプリケーションで少々利用したことがある 程度で、本格的な(企業システム等)では利用した経験が ありません。 最近はJavaで企業システムと言えば、J2EEベースのWebアプリケーションが 大半だと思いますが、その場合でも ・トランザクション中のConnectionをThreadLocalにする ・ユーザの認証情報をThreadLocalにする 等の利用方法があり、今まではシングルトンにしたり、 メソッドのパラメタで持ち回りしたりしていたオブジェクトを 利用しやすい場所に保持させることができると思っています。 # そう言えば、JTAの実装等もThreadLocalを利用しているような気がしますね。 反面、スレッドと言う比較的難易度の高い要素を扱うことや、 パフォーマンス面(最近は改善されたようですが、1.3.x以前のJ2SEでは かなり遅かった?)で問題はないだろうか、と言うところが気になり、 ThreadLocalの使用は慎重にすべきだとも考えます。 つきましては、皆様のThreadLocalを使用した経験談(こんな利用方法がある、 ThreadLocalなんて使えない..等)をお聞かせ願えませんでしょうか? よろしくお願いします。 | ||||||||||||
|
投稿日時: 2004-09-17 15:25
私自身は実際の企業システムで何度か利用したことがありますし、
利用しているのを見たこともあります。 実用に関して問題になったことはなく、リソース、コネクションの 開放漏れと、自由に取り出せると言う'弱点'に気を使えば、 問題ないと思います。 遅さ、という意味では特に実感したことはないですが、 そういえばIBMのコラムに「速くも遅くも無い」と書いてあった 記憶があります。 | ||||||||||||
|
投稿日時: 2004-09-17 22:06
「ワーカースレッド+タスクキュー」を用いるプログラムの基盤部分の
開発で、スレッド単位のコンテキストの保存位置として利用した覚えが あります。 当時は、「性能要件が厳しいならJavaは使わない」という方針でしたので、 性能が問題になることはなかったですね^^; ワーカースレッドパターンは、JDK1.5のConcurrent APIにそのまま実装 されるようですし、JDK1.6以降で導入される予定と伺っているIsolation APIあたりが整備されてくると、マルチスレッドプログラミングの小手先 テクニックなどは無用の長物になってしまうかな、それはよいことなのだ けれど、ちょっと寂しいかな、と思う今日この頃でした。 | ||||||||||||
|
投稿日時: 2004-09-18 21:45
ThreadLocalに関しては私も以前から疑問に思っていた点がひとつあり、詳しい方があれば、教えてください。
ThreadLocalは保管場所が一箇所で名前空間などで領域を分けて使う、などといったことがありません。 したがって、複数のライブラリがそれぞれ勝手にThreadLocalを使うとつぶしあうような気がしているのですが、それは正しいでしょうか? また、それを標準化する動きはないのでしょうか? | ||||||||||||
|
投稿日時: 2004-09-19 00:25
YOU@ITです。
返信遅くなり申し訳ありません。
そこは心配な点のひとつですね。 言い方は悪いですが、平均的なプログラマを集めて開発を行うような よくある開発スタイルの場合、全員がその辺のスキルを有していることは 期待できないですからね。 そういう意味でも。。。
シュンさんが利用された場合のように、ThreadLocalの利用は 基盤・フレームワーク部分に極力隠蔽するべきなのかな、と思いました。 ちなみにワーカスレッドパターンは知らないパターンでした。 情報ありがとうございます。ちょいと調べてみます。 # Webばっかりやっているとスレッドから遠ざかるもので。。。
なんとも微妙な表現ですが、よほど使用方法を誤らない限りは ボトルネックにはならないと言うことですね。 | ||||||||||||
|
投稿日時: 2004-09-19 00:39
# 質問の意図をはずしていたらすみません。 J2SEのAPIドキュメントのサンプルコード(http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ThreadLocal.html) にもあるように、ThreadLocalを利用する際は通常そのサブクラスを作成して 利用すると思います。 ThreadLocalのソースを見てみると、ThreadLocalのサブクラス(のインスタンス)を キーにしてMapコレクションに値を保持するようです。 ですので、ThreadLocalのサブクラス毎の名前空間が存在するような形になり、 複数のクラスからThreadLocalを利用したとしても競合するようなことはないと思います。 | ||||||||||||
|
投稿日時: 2004-09-19 01:25
詳しくないんであれですが、ドキュメントを読んだ限りでは「ThreadLocalのサブクラス毎の名前空間が存在するような形になり」ではなく、単純にThreadLocalのインスタンス毎に領域が確保されてるってだけではないでしょうか。 # サブクラスを作るのは単にそういう使い方があるってだけですよね? | ||||||||||||
|
投稿日時: 2004-09-19 12:18
ソースコードを読んでみました。
JDK1.4では、ThredLocalに保存するオブジェクトは、実際にはThreadインス タンスのメンバフィールドである、一種のマップオブジェクトに保管されます。 ThreadLocalのgetter/setterメソッドは、上記のマップオブジェクトに対して アクセスを行う、一種のビューのような役割を担当しています。 #Thread#currentThread()呼び出しで、現在のコンテキストを実行しているTh #readオブジェクトがいつでもどこでも取り出せる、というのがミソになって #います。 このマップには、「ThreadLocalインスタンス自身」をキー、ThreadLocalに 格納しようとするオブジェクトを値とするエントリが格納されます。 よって、「複数のライブラリがそれぞれ勝手にThreadLocalを使うとつぶしあ う」ということは、その複数のライブラリが、ThreadLocalインスタンスを個 別に作成して利用している限り、発生しません。 ということで、必要十分な程度には賢く出来ているようです。安心です。^^; | ||||||||||||
