- ベストアンサー
マルチスレッド下でのインスタンス変数・クラス変数
- マルチスレッド下で動作するクラスを作成し、データにアクセスするためのオブジェクトを保持する方法について悩んでいます。
- データアクセスオブジェクト(Dao)は全てローカル変数のみで動作し、フィールドは使用されません。
- クラス変数とインスタンス変数のどちらがメモリ効率が良いかという点で悩んでいます。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
staticフィールドはよいと思いますよ。フィールド定義でオブジェクトを new するか、 static 初期子で初期化すれば、初期化時におけるスレッドの競合を避けられるので 問題ないし、全てのスレッドから可視のオブジェクトができます。 ただし、Daoオブジェクトがクラス変数もインスタンス変数も持たなくても 処理に必要な内部オブジェクトや外部への参照がスレッドセーフでない 可能性があるので注意が必要でしょう。 普通にシングルトンするという手もあります。
その他の回答 (4)
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
>FactoryやSingletonのようなパターンを使用する場合、生成するオブジェクトをあらかじめstaticフィールドの変数として保持しておいて、それを返すといったcodeをよく目にします。 >どれも、実体は同じであるオブジェクトへの参照となるのですが、これもマルチスレッド下で使用することは危険と捉えるべきなのでしょうか? 以下ページの「まとめ」の「◎マルチスレッド環境での使用」を参照して下さい。 http://www.nulab.co.jp/designPatterns/designPatterns2/designPatterns2-1.html
お礼
遅くなりましたが、ご回答ありがとうございました。
- teketon
- ベストアンサー率65% (141/215)
ちょっと勘違いがあるようなので >FactoryやSingletonのようなパターンを使用する場合、生成するオブジェクトをあらかじめstaticフィールドの変数として保持しておいて、それを返すといったcodeをよく目にします。どれも、実体は同じであるオブジェクトへの参照となるのですが、これもマルチスレッド下で使用することは危険と捉えるべきなのでしょうか? デザインパターンは、クラス設計のパターンなだけであり、スレッドセーフを保証する仕組みではありません。マルチスレッド環境でのスレッドセーフが要求される場合、独自に対応する必要があります。 あと、Javaではスレッドチェンジを抑制することはできません。 Synchronizedブロックを使用しても、オブジェクトにロックが掛かるだけです。
お礼
遅くなりましたが、ご回答ありがとうございました。
- teketon
- ベストアンサー率65% (141/215)
スレッドセーフなのは当然として。 staticにするか否かは、インスタンス数を決定することであり、インスタンス生成のコストにより決めます。 インスタンス生成のコストが深刻ならばシステムに付き1つ、 上限を設けたいならばオブジェクトのプーリング、 生成コストよりも処理数を上げるならば、インスタンス数は呼び出し側で決定するなどです。 私ならば、インスタンス変数にしてしまい、フレームワークでインスタンス数を決めます。 安易にstaticを使用すると、テストが困難になったり、再現性のないバグの元です。
お礼
遅くなりましたが、ご回答ありがとうございました。
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
>マルチスレッド下で動作するクラスを作成しています。 だったらスレッドセーフに作らんとイカンだろ? >staticなクラス変数が良いのか staticなクラス変数は「誰かがこのクラスを既に使用中で、二重には使えない」って場合に、二重実行を監視する為に使う。 例えば、誰かがデータのレコードを読み込んで、一部だけ書き換えてアップデートする場合、アップデートが終わるまで、レコードを保持している変数と、書き換えたいレコードは「他のスレッドではアクセスしちゃいけない」のは自明。 そういう場合は「どのスレッドからも見える、ただ1つのフラグ変数」が必要になる。そのフラグが付いてたら「触るな」って事だから。 変数をstaticで置く場合は「その変数の使用開始から使用終了まで、一切、スレッドチェンジが起きない事」を保証しないといけない。 APIコールやOSコールを行うと、OSで勝手にスレッドチェンジが入るから「スレッドチェンジが起きない事」ってのは「APIコールやOSコールを一切使わず、CPUを占有する」ってこと(そして、そういうプログラムは忌避される) マルチスレッドを軽く考えてると「思いもよらないバグ」で1~2ヶ月は泣かされる事になる。
お礼
遅くなりましたが、ご回答ありがとうございました。
補足
chie65535様 丁寧なご回答ありがとうございます。自分の勉強不足を痛感しております。 一点質問がございます。 FactoryやSingletonのようなパターンを使用する場合、生成するオブジェクトをあらかじめstaticフィールドの変数として保持しておいて、それを返すといったcodeをよく目にします。どれも、実体は同じであるオブジェクトへの参照となるのですが、これもマルチスレッド下で使用することは危険と捉えるべきなのでしょうか? ご回答への質問となってしまい申し訳ございませんが、よろしくお願い致します。
お礼
遅くなりましたが、ご回答ありがとうございました。