- - PR -
オブジェクトの参照について
| 投稿者 | 投稿内容 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2002-04-19 09:45
> すみません、ちょっと違います。
いえ、全然ちがいましたね。 件名が「オブジェクトの参照について」なので誤解してしまいました。 > 答を見て、初めてWeakHashMapをリファレンスで引いてみました:oops: > 削除したくなった段階で、WeakHashMapに入れてやると、 > ユーザが使い終わったら、GCが開放してくれるということでしょうか? > ほったらかしにするよりは、確実に(早く?)削除されるのでしょうか? WeakHashMapは、その名の通り「弱い参照」によってオブジェクトを登録するHashMapです。Javaでは誰からも参照されていないオブジェクトはGCによって開放されますが、逆に誰かが参照していれば開放されません。この通常の参照を「強い参照」とすると、弱い参照はそれ自身だけの参照はGCの対象になってしまうというものです。 WeakHashMapに登録されたオブジェクトは、だれか別のオブジェクトによって強い参照によって参照されている限りはGCの対象にはならず、他から参照されなくなってWeakHashMapからしか参照されなくなったら、それは弱い参照なのでGCの対象になる、ということだと理解しています。普通は勝手にGCが回収したら困るので、用途としてはキャッシュが思い付きます。 APIリファレンスよりも「プログラミング言語Java第3版」pp.321-327にもっとわかりやすい解説があります。 | ||||||||||||
|
投稿日時: 2002-04-19 12:25
皆様、詳細なご回答ありがとうございます。
私の説明がかなり不足していたようです。すみません。 >> H2様 >checkInXXX()とcheckOutXXX()でオブジェクトの管理をすれば良いわけです。 >これなら、他からのxxxオブジェクトのアクセスもcheckOutXXX()で >制限されますので、他のメソッドにsynchronizedもなくても良いはずです。 >よって多少の排泄処理にかかるオーバーヘッドを減らせるはずです。 >(うーん。正しいですよね?) コードまで書いていただいて、ありがとうございます。 確かにこれなら、「誰が参照しているか」まで分かりますね。 ただ、XXXインスタンスへのアクセスが排他的になってしまうので、 やりたいこととはちょっと違ってしまいます。 (説明不足でした、すみません) >> YOU@IT様 >(仕様は割愛させていただきます) >もし、上記のような仕様であれば、そもそもXxxの参照をB(B’)が >取得する事自体が間違っているのではないでしょうか? やりたいことは、ご指摘の仕様とほぼ同じです。 ただ、B及びB’が順番にXxxインスタンスを使用するのではなく、 同時に使用します。 それぞれの実行結果が残っていることに問題はないのですが、 機能として、万一、Xxxの状態に不整合が生じてしまった場合などに、 それをクリアするメソッドを実装したいということです。 メソッド自体はできているのですが、 Xxxインスタンスの利用側インスタンスが、使用している 間に実行してしまうと、エラーをはいてしまうので避けたいのです。 >ペンギン様が最初に提示されたサンプルコードを見ても、 >AがXxxのインスタンスを管理する言わばマネージャとしての >役割を持っていると思います。 >であれば、BがXxxのメソッドを直接実行するのではなく、 >AがXxxのメソッドをラップしてBに公開し、 >BはAのメソッドを利用するほうが、Aに制御が集中していいと思うのですが。 まさにご指摘の通り、AはXxxのマネージャーです。 はじめのうちはラップしていたんですが、 Xxx自身がまた別のオブジェクトのマネージャーなので、 実装したいメソッドが増えてしまい、 それなら、Aは単にXxxを管理するだけにしようと思って、 Xxxを提供するメソッドを実装しているという感じです。 >ちょっとわかりにくい文章かもしれませんが・・・ >要はクラスの責任が明確になっていないのでは?と言う事を言いたいわけです。 >外していたらごめんなさい いえいえ自分の方こそ、説明不足ですみませんでした。 >と言う事は、Xxxのいくつかのメソッドがひとまとまりになって >1つのトランザクションになっているのではないですか? >トランザクションの観点から見ても、やはりクラスAでXXXのメソッドを >ラップする形で1トランザクションを実行するメソッドを提供すべきでは >ないかと思えるのですが。 トランザクションの単位としては、それぞれのメソッド単位になります。 そういう意味でsynchronizedをかけてあります。 「割と長い時間をかけて」というのが表現として間違っていました。 YOU@IT様のコードで言いますと、xxx.firstMethod(param)を実行した後、 Xxxインスタンスの利用側インスタンスで、独自の処理を行った後、 xxx.secondMethod(param)を実行するようなイメージです。 「割と長い時間、Xxxインスタンスの参照を保持している」というのが、 正しい表現でしょうか(まだ変ですね・・・) >> しょむ様 >それって、タスクキューというのでは… >実装が面倒なら TimerTask を使えないかな… YOU@IT様が言われた仕様だと、そうなりますね。 >あと、参照の話なら、クラスではなくインスタンスでお話ししないと混乱します。 すみません、私も混乱してしまっています。 切り出しがよくありませんでした。 >> miki様 >いえ、全然ちがいましたね。 >件名が「オブジェクトの参照について」なので誤解してしまいました。 参照されているかが分かれば、解決するかなと思って、 安易に書き込みしてしまいました。すみません。 WeakHashMapの説明、ありがとうございます。 普段はあまり目にしないクラスですが、使い方を きちんと整理できれば、設計に幅が出ますね。 こういうのは結構好きなので、いろいろ実験してみます。 | ||||||||||||
|
投稿日時: 2002-04-19 13:43
もうすこし要求仕様を明確にした方が良さそうですね。
任意の Object A1,A2,... が、それぞれ XXX B1,B2,... を持っている。 B* は何か共通のリソースを排他的に利用する(synchronized) A* のすべてが B* を解放している場合に限り実行したい処理がある(クリア) class XXXFactory { static private int cnt = 0; static private check = false; static XXX getXXX(param) { cnt++; .. } static void removeXXX(XXX a) { a=null; cnt--; ... clear(); } static void clear() { if (check==true && cnt==0) { ... } } } こんなかんじ? 外で B? = null されるのがいやなら、B さんに自分の産みの親の参照を保持しておいて、finalize でどうにかするとか。Listerner をつっこむとか。 | ||||||||||||
|
投稿日時: 2002-04-19 19:01
題名は"並列プログラミングのオブジェクトのロック"がよさそう。
一度、Javaスレッドプログラミングの立ち読みを薦めます。 著者ダグ・リーのページ util.concurrent
基本的にfinalizeの使用はしない方が良いみたいです。 詳しくは、以下の本に書かれています。 Effective Javaの項目6 ファイナライザを避ける。 | ||||||||||||
|
投稿日時: 2002-04-21 22:03
ご返答ありがとうございます。
>> しょむ様
要求使用を明確にしていただいてありがとうございます。 自分では文章にできなそうでした・・・。 コードの方も参考にさせてもらいます。 >> hatena様
なるほど、端的に言うとそうなりますね。 ご紹介の本、たぶん本屋で見かけた気がするので、 立ち読んでみます(安月給の私には買えそうになかったような・・・)。
たしか、実行されない場合があるとかでしたっけ・・・ JavaHouseで読んだような・・・ これも調べて見ます。ありがとうございました。 | ||||||||||||
|
投稿日時: 2002-04-22 10:31
finalizeがいつ行われるかはVMのみぞ知る、ということですね。
ロックの解除をfinalizeでやったつもりでも、実は解除できてないというのが起きてしまう。 | ||||||||||||
