synchronized もホドホドに?

久々にお仕事の話。人のソースをCDIしていたらとあるwrapperクラスで気になるソースを発見。
記憶が確かならこんなソースだったかと。

public class Hoge {
    private InitialContext context = null;
    public Hoge() throws NamingException {
        context = new InitialContext();
    }
    public void bind(String name, Object object) throws NamingException {
        this.context.bind(name, object);
    }
    public Object lookup(String name) throws NamingException {
        return this.context.lookup(name);
    }
}

一見、問題なさそうですけど、内包するInitialContextに対して読み書きするクラスのようで。
このクラス(インスタンス)に同時にアクセスするスレッドがいるならば・・・排他が必要ですね。
ということで、synchronizedで同期化してみます。

  • ブロックでの宣言
  • メソッドでの宣言

2通りありますが、有名なPMDでは、「AvoidSynchronizedAtMethodLevel」なるルールがあったりして、
今回は1行なのでどちらでも良いかも知れないけど、前者がいいらしい。

Method level synchronization can backfire when new code is added to the method. Block-level synchronization helps to ensure that only the code that needs synchronization gets it.

和訳すると、

メソッドレベルでの synchronized 構文の使用を検出します。このようにすると、そのメソッドに処理が追加された場合にそれら全ても同期化されてしまいます。出来る限り同期化の範囲を限定することを望むならば、これはあまり良くない事です。

マルチスレッド環境下では限りなく性能を考慮しなさいってことですかね。