Javaと言っても今回はj2ee。
sessionにコレクション系クラスのオブジェクトを最初に突っ込んで、それをgetしてきてコレクションに要素を追加、再びsetし直すみたいなコードを書いたんだけど、よくよく考えたら getした参照からsession弄りたい放題じゃね?と思って別にsetし直す必要ないよねー的なことを報告書に書いて提出したら、この前の金曜日の飲み会で「挑戦的な報告を受け取ったから自宅の環境で試しにやってみたんだけど再現しなかった~」と言われてしまい、なぬー?と思い少し実装がどうなってるのか気になったので調べてみた。
HttpSessionはインタフェースなので実装クラスがまずなんなのか調べる。
→org.apache.catalina.session.StandardSessionFacadeというクラスらしい。
apache tomcatのホームページからソースを取得。
今回はtomcat-4.1.37
tomcat-5.5.26
tomcat-6.0.16の3つを調べた。
StandardSessionFacadeはあくまでもStandardSessionのラッパー的存在なのでStandardSessionの方を見ます。
まず\apache-tomcat-4.1.37-src\container\catalina\src\share\org\apache\catalina\session
public Object getAttribute(String name) { if (!isValid) throw new IllegalStateException (sm.getString("standardSession.getAttribute.ise")); synchronized (attributes) { return (attributes.get(name)); } }
ちなみにattributesの宣言はprivate HashMap attributes = new HashMap();
HashMapは同期化されないのでsynchronized でくくってますね。
\apache-tomcat-5.5.26-src\container\catalina\src\share\org\apache\catalina\session
public Object getAttribute(String name) { if (!isValid()) throw new IllegalStateException (sm.getString("standardSession.getAttribute.ise")); return (attributes.get(name)); }
attributes の宣言はprotected Map attributes = new Hashtable();
Hashtableは同期化されるのでsynchronized ブロックがごっそり消えてるね。
てかHashtableの存在を今まで知りませんでした( ; ´Д`)
\apache-tomcat-6.0.16-src\java\org\apache\catalina\session
public Object getAttribute(String name) { if (!isValidInternal()) throw new IllegalStateException (sm.getString("standardSession.getAttribute.ise")); return (attributes.get(name)); }
attributes の宣言はprotected Map attributes = new ConcurrentHashMap();
HashtableをConcurrentHashMapに置き換えてパフォーマンスアップしてるらしい。
参考:Javaの理論と実践: 並行コレクション・クラス
なんかHash系クラスの紹介になりつつあるが、どうやらgetでオブジェクトのコピーを渡しているわけではなさそうだ。
多分報告書を大分はしょって書いたので講師の方はstringとかの不変クラスをぶちこまれたのではなかろうか?自分の言葉足らずだったかも。てか冒頭の方法はそもそもカプセル化破壊を利用しちゃってるしなぁ。混乱を招かないためにもgetしたらsetし直すという方針がHttpSessionの正しい使い方なのかも。