2009-07-27 16 views
3

我々は以下の方法(のorg.apache.struts.util.MessageResourcesクラス)​​への同時アクセスを保証するために、同期を使用する必要がありますので、ダブルチェックロックの問題があるので:Struts 1.2.7のMessageResourcesFactoryの遅延インスタンス化はなぜですか?

LAZY INSTANTIATION

public synchronized static MessageResources getMessageResources(String config) { 

    if (defaultFactory == null) { 
     defaultFactory = MessageResourcesFactory.createFactory(); 
    } 

    return defaultFactory.createResources(config); 
} 
は、

なぜ使用しない:

EAGER INSTANTIATIONその後、

static { 

    // Construct a new instance of the specified factory class 
    try { 
     if (clazz == null) 
      clazz = RequestUtils.applicationClass(factoryClass); 
     MessageResourcesFactory defaultFactory = 
      (MessageResourcesFactory) clazz.newInstance(); 
    } catch (Exception e) { 
     LOG.error("MessageResourcesFactory.createFactory", e); 
    } 

} 

そして:

public static MessageResources getMessageResources(String config) { 

    return defaultFactory.createResources(config); 
} 

これは、getMessageResourcesメソッドへの同時アクセスを許可します。これは、少なくとも私の場合、かなり数回呼び出される可能性があります。同期を使用していない

意味はここにある:

http://en.wikipedia.org/wiki/Double-checked_locking

答えて

0

私は、org.apache.struts.util.MessageResourcesをオーバーライドする人がcreateResources(文字列の設定)を同期化して定義しているかどうかに関係なく、マルチスレッドモードでStrutsがうまく動作することを確認する方法だと思いますない。

0

現代のJVM上で同期の方法で発生するオーバーヘッドは微々たるものになるように小さいです。同期lazy-initファクトリメソッドへのその後の呼び出しは、同期化されていないeager-initメソッドの呼び出しとほぼ同じくらい速くなります。

lazy-initアプローチは、静的なイニシャライザブロックを使用するよりも、わかりやすく簡単です(私の意見では)。また、静的initブロックが失敗した場合、どこと理由を把握するのが非常に混乱する可能性があります。

0

MessageResourceFactoryを初期化することができない理由がない限り(たとえば、特定のサーブレットリソースを最初に初期化する必要があるなど)、私はあなたのソリューションがよかったと思います。私は、Strutsチームが、この作業に携わった特定の開発者が慣れていること以外は、工場を遅延ロードする理由がないと推測します(必要でないときでも、シングルトンを遅延ロードする傾向があります)。

バグレポートを提出して解決策を提案しましたか?

+0

なぜそれらは複数回作成されますか? – skaffman

+0

申し訳ありませんが、私はコードを誤って読んでいない、私は方法が同期されていないと思った、それはクライアントにそれを同期することでした。私は私の質問は、メソッドが同期されていない場合、それは大きな問題になると思いますか? –

+0

はい、不完全に初期化されたオブジェクトへの参照を取得する可能性があるため、マルチスレッド環境では問題になります。 –

1

MessageResourcesFactoryはスレッドセーフですか?​​メソッドは、フィールドの設定とcreateResourcesメソッド呼び出しの両方を保護します。スレッドセーフな場合は、フィールドを設定するだけでロックを移動し、メソッド呼び出しをクリティカルセクションの外に置いておくことができます。

関連する問題