• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:マルチスレッド下でのインスタンス変数・クラス変数)

マルチスレッド下でのインスタンス変数・クラス変数

このQ&Aのポイント
  • マルチスレッド下で動作するクラスを作成し、データにアクセスするためのオブジェクトを保持する方法について悩んでいます。
  • データアクセスオブジェクト(Dao)は全てローカル変数のみで動作し、フィールドは使用されません。
  • クラス変数とインスタンス変数のどちらがメモリ効率が良いかという点で悩んでいます。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.5

staticフィールドはよいと思いますよ。フィールド定義でオブジェクトを new するか、 static 初期子で初期化すれば、初期化時におけるスレッドの競合を避けられるので 問題ないし、全てのスレッドから可視のオブジェクトができます。 ただし、Daoオブジェクトがクラス変数もインスタンス変数も持たなくても 処理に必要な内部オブジェクトや外部への参照がスレッドセーフでない 可能性があるので注意が必要でしょう。 普通にシングルトンするという手もあります。

takepan_toki
質問者

お礼

遅くなりましたが、ご回答ありがとうございました。

その他の回答 (4)

回答No.4

>FactoryやSingletonのようなパターンを使用する場合、生成するオブジェクトをあらかじめstaticフィールドの変数として保持しておいて、それを返すといったcodeをよく目にします。 >どれも、実体は同じであるオブジェクトへの参照となるのですが、これもマルチスレッド下で使用することは危険と捉えるべきなのでしょうか? 以下ページの「まとめ」の「◎マルチスレッド環境での使用」を参照して下さい。 http://www.nulab.co.jp/designPatterns/designPatterns2/designPatterns2-1.html

takepan_toki
質問者

お礼

遅くなりましたが、ご回答ありがとうございました。

  • teketon
  • ベストアンサー率65% (141/215)
回答No.3

ちょっと勘違いがあるようなので >FactoryやSingletonのようなパターンを使用する場合、生成するオブジェクトをあらかじめstaticフィールドの変数として保持しておいて、それを返すといったcodeをよく目にします。どれも、実体は同じであるオブジェクトへの参照となるのですが、これもマルチスレッド下で使用することは危険と捉えるべきなのでしょうか? デザインパターンは、クラス設計のパターンなだけであり、スレッドセーフを保証する仕組みではありません。マルチスレッド環境でのスレッドセーフが要求される場合、独自に対応する必要があります。 あと、Javaではスレッドチェンジを抑制することはできません。 Synchronizedブロックを使用しても、オブジェクトにロックが掛かるだけです。

参考URL:
http://www.ibm.com/developerworks/jp/java/library/j-dcl/
takepan_toki
質問者

お礼

遅くなりましたが、ご回答ありがとうございました。

  • teketon
  • ベストアンサー率65% (141/215)
回答No.2

スレッドセーフなのは当然として。 staticにするか否かは、インスタンス数を決定することであり、インスタンス生成のコストにより決めます。 インスタンス生成のコストが深刻ならばシステムに付き1つ、 上限を設けたいならばオブジェクトのプーリング、 生成コストよりも処理数を上げるならば、インスタンス数は呼び出し側で決定するなどです。 私ならば、インスタンス変数にしてしまい、フレームワークでインスタンス数を決めます。 安易にstaticを使用すると、テストが困難になったり、再現性のないバグの元です。

takepan_toki
質問者

お礼

遅くなりましたが、ご回答ありがとうございました。

回答No.1

>マルチスレッド下で動作するクラスを作成しています。 だったらスレッドセーフに作らんとイカンだろ? >staticなクラス変数が良いのか staticなクラス変数は「誰かがこのクラスを既に使用中で、二重には使えない」って場合に、二重実行を監視する為に使う。 例えば、誰かがデータのレコードを読み込んで、一部だけ書き換えてアップデートする場合、アップデートが終わるまで、レコードを保持している変数と、書き換えたいレコードは「他のスレッドではアクセスしちゃいけない」のは自明。 そういう場合は「どのスレッドからも見える、ただ1つのフラグ変数」が必要になる。そのフラグが付いてたら「触るな」って事だから。 変数をstaticで置く場合は「その変数の使用開始から使用終了まで、一切、スレッドチェンジが起きない事」を保証しないといけない。 APIコールやOSコールを行うと、OSで勝手にスレッドチェンジが入るから「スレッドチェンジが起きない事」ってのは「APIコールやOSコールを一切使わず、CPUを占有する」ってこと(そして、そういうプログラムは忌避される) マルチスレッドを軽く考えてると「思いもよらないバグ」で1~2ヶ月は泣かされる事になる。

takepan_toki
質問者

お礼

遅くなりましたが、ご回答ありがとうございました。

takepan_toki
質問者

補足

chie65535様  丁寧なご回答ありがとうございます。自分の勉強不足を痛感しております。    一点質問がございます。  FactoryやSingletonのようなパターンを使用する場合、生成するオブジェクトをあらかじめstaticフィールドの変数として保持しておいて、それを返すといったcodeをよく目にします。どれも、実体は同じであるオブジェクトへの参照となるのですが、これもマルチスレッド下で使用することは危険と捉えるべきなのでしょうか?  ご回答への質問となってしまい申し訳ございませんが、よろしくお願い致します。