Java/Importance/Specification

Last-modified: 2008-02-27 (水) 17:59:26

Specification

synchronized

マルチスレッド処理に欠かせない修飾子です。複数のスレッドからあるインスタンスに対してアクセス(参照・追加・削除など)がある場合スレッドをブロックしてインスタンスのデータの整合性を取ります。非常に重要な修飾子なので完全に理解すべきもののひとつです。

synchronizedメソッド

スレッド間でのインスタンスの同期を取るための修飾子です。同期を取りたいフィールド変数が存在した場合、synchronizedメソッドにすることにより簡単に同期を取ることが可能となります。ただし下記の点に注意する必要がある。

  • 同じクラスに存在するその他の synchronizedメソッドに対しても影響を及ぼす
    例えば下記のようなクラスAが存在するとする。
    public synchronized void add(String str);
    public synchronized void remove(String str);
    public void getName();
    このクラスAのインスタンスはaddメソッドがスレッド1から呼び出されている間、スレッド2がremoveメソッドを呼び出してもスレッド1のaddメソッドの呼び出しが終わるまでブロックされます。
    しかしsynchronizedでないメソッドに対しては同期化されないことも理解すべき重要なことです。
    上記の話を例にするとこのクラスAのインスタンスはaddメソッドがスレッド1から呼び出されている間、スレッド2がgetNameメソッドを呼び出してもスレッド1のaddメソッドの呼び出しが終わるまでブロックされず、即座にスレッド2はgetNameメソッドを呼び出すことができます。

このことからsynchronizedメソッドを使用することによりスレッド間で無関係な待ち状態が発生しうることがあります。例えばaddメソッドと、remove()メソッドが別の変数に対して処理を行っていた場合addメソッドと、removeメソッドは同期する必要はありません。筆者の観点では、極力synchronizedメソッドは使用せずにsynchronizedメソッドブロックを使用することをお勧めします。

synchronizedブロック