目次 | 前項目 | 次項目 内部クラス仕様


内部クラスは Java コードの正しい同期に影響するか?

内部クラスは 1 つの(または複数の)親クラスの実装の一部です。そのため、これはすべての親クラスの private メンバにアクセスします。これは、プログラマが private 変数に格納された状態への併行アクセスの可能性に注意し、非 private メソッドが正しく同期しているのを保証する必要があることを意味します。時にこれは、親メソッドを synchronized キーワードで宣言する必要があることだけを意味します。

FixedStack およびその列挙子のように、1 つ以上のオブジェクトが関わるとき、プログラマはどのインスタンスを同期化するかを選択し、親インスタンスに対して次のように明示的な synchronized 文を書く必要があります:

            public Object nextElement() {
                ...
                synchronized (FixedStack.this) {
                    return array[--count];
                }
            }

内部クラスの synchronized メソッドと親インスタンスの間に特別な関係はありません。親インスタンスと同期化するためには、明示的な synchronized 文を使用します。

マルチスレッドコードを書くとき、プログラマは共有された状態変数への潜在的な非同期アクセスに常に注意する必要があります。非同期内部クラスは、 private フィールドまたはローカル変数を共有するスレッドの作成を極めて簡単にします。プログラマはこれらの変数へのアクセスを同期化すること、または各スレッドに対して別個のコピーをすることのどちらかに配慮する必要があります。例えば、この for ループは index 変数のコピーをする必要があります:

        for (int ii = 0; ii < getBinCount(); ii++) {
            final int i = ii; // capture a stable copy for each thread
            Runnable r = new Runnable() {
                public void run() { processBin(i); }
            };
            new Thread(r, "processBin("+i+")").start();
        }

内部クラス本体内でループ添字を使用しようとすることはよくある間違いです。添字は final でないため、コンパイラがエラーの報告をします。


目次 | 前項目 | 次項目

内部クラス仕様 (HTML generated by dkramer on March 15, 1997)
Copyright (c) 1996, 1997 Sun Microsystems, Inc. All rights reserved
コメントや訂正は john.rose@eng.sun.com 宛てに送ってください。