- - PR -
staticメソッドについて
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2004-06-28 17:27
皆さん、こんにちは。
早速ですが static メソッドについて質問があります。 static変数を使わずにstatic メソッド内に全てのオブジェクトを生成して 処理をする時、staticメソッドはスレッドセーフになるのでしょうか? 例: public static void testStatic(String name){ ArrayList list = new ArrayList(); for (int i=0; i<10; i++ ){ list.add( name + ":i=" + i ); //時間処理を記述 } for ( int i=0; i<list.size(); i++ ) { System.out.println( ( (String)list.get[i] ).toString() ); } } (こうではなく private static ArrayList list; public static void testStatic(String name){ list = new ArrayList(); for (int i=0; i<10; i++ ){ list.add( name + ":i=" + i ); //時間処理を記述 } for ( int i=0; i<list.size(); i++ ) { System.out.println( ( (String)list.get[i] ).toString() ); } } こうするとスレッドセーフでないことは理解できました。) 試した結果、スレッドセーフっぽいのですが理由がわかりません。 自分の理解ではstaticなものはそのJVMの中で唯一のものと思っていますが、 仮に↑の例でAさんが処理している間にBさんが同じメソッドを使用すると 結果に影響がでてくると思ってました。 (例えばこんな感じに Aさん:i=0 Aさん:i=1 Aさん:i=2 #Bさんが割り込み Bさん:i=0 Bさん:i=1 Bさん:i=2 ・・・ 以下Bさんで最後まで) もし、仮にこのようなstaticメソッドがスレッドセーフの場合、 よく使う共通関数を全てこのようなstaticにした場合なにか 不都合なことが起こるのでしょうか?(プログラムが不安定になるとか・・・) それともstaticメソッドを使わないより効率がいいのでしょうか? (スレッドセーフならその共通関数を保持しているオブジェクトを 毎回newする必要がないのでパフォーマンスがあがる気がします。) 以上、すいませんがご教授ください。 | ||||
|
投稿日時: 2004-06-28 17:53
ローカル変数はスタックに確保されます。(「変数は」ですよ。オブジェクトそのものはヒープに置かれます)
スタックはスレッド毎に存在します。 なので、ローカル変数へのアクセスがスレッド間で競合するということはありません。 | ||||
|
投稿日時: 2004-06-29 12:42
佐々木さん
ご返答ありがとうございます。 メモリ関連のことは詳しくない(文献よんでもいまいち理解できません) ので助かりました。 ってことはstaticメソッドはstatic変数やメソッドを使うときに使用するもの または毎回そのメソッドをNewするのが面倒な時使用するもの という程度の認識でいいみたいですね。 あえてstaticにしてもあまりパフォーマンスとか変わりそうにないので・・・ | ||||
|
投稿日時: 2004-06-29 13:12
作業空間内において、一意な存在である、という重要な役割・意味づけがありますよ。
この場合の「作業空間内」というのは、たしかプロセスでよかったかと。 このへんははっきりして無くてすみません(汗 newする必要がない、というか許されていないのはそのためです。 オブジェクト指向を学習されてはいかがでしょうか。 [ メッセージ編集済み 編集者: Edosson 編集日時 2004-06-29 13:18 ] | ||||
|
投稿日時: 2004-06-29 15:37
Edossonさん、早速のご回答ありがとうございます。
自分にとってstaticメソッドの場合、「一意な存在」というのが static変数ほど重要ではないような気がするのですが・・・ (継承できないのがいたいですが・・・) というか定義がわかりにくかったです。 最初に書いたみたいに処理まで一意なのかと・・・ で、オブジェクト指向ってあまりstaticメソッドとか触れてないような 気がしますが(デザインパターンのシングルトンぐらいかな?) [ メッセージ編集済み 編集者: Tom 編集日時 2004-06-29 15:39 ] | ||||
|
投稿日時: 2004-06-29 16:08
staticな変数やメソッドを継承しようなんて考えちゃだめです。
でないと、なんのためのstaticなんだか、わからなくなっちゃいます。 <追記 ここから> 上で、なんか妙なこと書いてます。 privateとstaticが混ざっちゃったのか。失礼しました。m(_ _)m <追記 ここまで> 自分の知識の範囲だけで、一般の技術を語るのは危険かと。 実際に現実の世界で運用されているんです。ちゃんと勉強しないともったいないですよ。 私もえらそうには言えませんが。(^ ^; 最近、オブジェクト指向がもてはやされていますが、 現実には、「継承」ひとつとっても、差分プログラミングの手段として、 お手軽に利用されているというのも多いんでしょうね。 [ メッセージ編集済み 編集者: Edosson 編集日時 2004-06-29 16:26 ] | ||||
|
投稿日時: 2004-06-29 18:33
それでよいと思います。あまり難しく考えることありませんよ。 インスタンス化不能でstaticメソッドしか持たない、単なる関数置き場みたいなクラスを「オブジェクト指向っぽくない」と眉をしかめる向きもあるでしょうが、いいじゃないですか役に立てば。 java.lang.Mathとか、java.util.Collectionsとか便利でしょ? | ||||
|
投稿日時: 2004-11-04 18:10
Factory Method とかでも使いますかね。 public abstract class Foo{ public static Foo createFoo(){ return new SimpleFoo(); } public abstract void doSomething(); } class SimpleFoo extends Foo{ public SimpleFoo(){ } public void doSomething(){ System.out.println("SimpleFoo: HelloWorld"); } } このとき, Foo foo = Foo.createFoo(); foo.doSomething(); みたいに使えば抽象型のコンストラクタ代わり(実際はデフォルトの実装クラスのですが)になります。応用を利かせるときは Abstract Factory パターンで抽象クラス(かインターフェイス)を作って非 static で継承させて使うほうがもちろんいいのですが、簡単な実装としてはアリかと思います。 (static でない)メソッドはインスタンス依存の処理をするのに対して、 static メソッド(フィールド(変数)もそうですが)はクラス依存の処理になります。static フィールドの getter/setter は static メソッドとして書くほうが理にかなってますしね。直接フィールドを外部から参照するのは static final な時だけにしてます ^^; # スレッドの投稿時間を見ずにレスを書いてしまいました… # せっかくなので、ここを見る誰かのご参考になればいいのですが。 [ メッセージ編集済み 編集者: hiro@Azure 編集日時 2004-11-04 18:29 ] |
1