[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 10184] Re: 「 Effective Jav  プログラミングガ



福嶋です。

On 2002.06.23, at 05:30, nemo_kaz wrote:

参加者
  佐藤慶治  村山敏清  荒井彩子  中村圭輔  門脇太郎  吉関 
コセキ 
天野 
  高橋(徹)  高橋(智)  福島航   山本貴士  伊藤哲   根本和郎
(記) 
鈴木 石黒

おっと、柴田さんが抜けていますよ。

○ volatileについて
  private volatile int hashCode =0;
   について intはアトミック処理をするが、読み出しの場合はvolatile必須。

longやdoubleはアトミック処理されないというお話も出ましたね。

○ hashmapに長いstringは入れるな
  ハッシュテーブルの構造は事前に、理解していること、hashそのものの説明
はな
い。

 hashcodeの計算は最初の数文字だけを見るのでhashが1個所に集中
することがあ
る。

これは、JDK1.xの頃のString#hashCode()の実装がそうだったという話ですね。

stringのhashmapはキャッシュするだけで早くなるかもしれない(テスト必要)。

J2SE v1.4 ではキャッシュしているかもしれない、という話でした
手元のMac OS Xに入っている
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-root-020219-20:07)
Java HotSpot(TM) Client VM (build 1.3.1, mixed mode)


で見てみたところ、ちゃんとキャッシュしていました。

    /** Cache the hash code for the string */
    private int hash = 0;
:
    public int hashCode() {
	int h = hash;
	if (h == 0) {
	    int off = offset;
	    char val[] = value;
	    int len = count;

	    for (int i = 0; i < len; i++)
		h = 31*h + val[off++];
	    hash = h;
	}
	return h;
    }

 toStringにMD5を使ってみるのはどうか、ユニークさを保って速く処理
できそう。
 詳しくはsource.jarを見ましょう

打ちミスと思いますが。src.jarですね。

 hashtableの複製とは新しいテーブルにコピーすること。
  super.clone()でhushtableを新規に作る。
  同じ手順で複製する。
  全く同じモノを同じように作る。

この辺は、内部のHashtable.Entryを複製するのではなく、旧インスタンスの 内容を getで取り出し、新インスタンスにputで追加していく、というものでした。 パフォーマンスを考えるとやっぱり前者だと思いますが。

  clone()メソッドにかかわらずコンストラクター デシリアライズは危険
メソッド
として注意がいる。
  極論すれば生成に関与するメソッドは全て注意すること。
  copyConstructor()を利用したほうが良い。

インスタンス生成中にインスタンスメソッドを呼ぶのは避けた方が良い、という 話の 流れでこの話が出ましたね。昔、コンストラクタでsetterメソッドを呼 んだりとかい うコードを書いてしまったことがありますが、「初期化とsetterメソッド はわける」 と別の本でも読んだ気がします。ちょっと話が違いますが。

  volatileの意味
     =Cは最適化指示
     =Javaではdoubleとlongのアクセスのアトミック性を保証すること。
         Synchronizeなしでも最新のデータを保証する。

上に私が書いた話はこの流れで出てきました。 しかし、synchronizedを使用せずに、volatileを工夫して使えば同期 がとれるとい うことは知りませんでした。プリミティブタイプの同期のためには、専用の 同期オ ブジェクトを作ったりしないといけないのが嫌だなあと思っていましたので、 目か らうろこですね。

p67
  ソース中resultローカル変数の存在意義はread once write onceの実現の為
  そうでないと訳注の様に、2回読み込みが発生して、値が変
わるおそれがある。
  参考(double-locked checkイディオム)

これも深いですね。気付きませんでした。上記String#hashCode()を見てみると、 やはり一旦ローカル変数に値をとっていますね。コーディングスタイルというか イディオムとしてこれはコーディング規約に書いて注意喚起 すべきかもしれません。

以上

お疲れ様でした。


---------------------------- Wataru Fukushima