チケット #40 (new defect)

登録: 9 年 前

最終更新: 9 年 前

ServiceManagerがスレッドアンセーフ

報告者: imart 担当者: system
優先度: critical コンポーネント: default
バージョン: キーワード:
関係者:

チケットの概要

org.intra_mart.framework.base.service.ServiceManager?のメソッド getServiceManager()がスレッドセーフではありません。 ダブルチェックロッキング(DCL)を行っているようですが、JavaのメモリモデルではDCLはスレッドセーフになりません。原因はJavaがスレッド毎にローカル変数やフィールドの値をキャッシュするからです。 また、managerFlag = new Boolean(true); というコードがあるので、たとえDCLに問題がなかったとしても、DCLが正しく機能しません(ロック中にロック対象のフィールド値が変更されてしまうため)。

おそらく、処理を高速化するためにDCLを行っているのだと思いますが、現在のJava VMはsynchronizedをしても十分に速いので、DCLをやめた方が良いのではないでしょうか。

あるいはどうしてもDCLをするならばvolatileキーワードを使えば問題は解決すると思います。

Javaのスレッド処理については、このあたりの本が参考になるのでどうぞ。DCLについても載っています。 http://www.amazon.co.jp/Java%E4%B8%A6%E8%A1%8C%E5%87%A6%E7%90%86%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E2%80%95%E3%81%9D%E3%81%AE%E3%80%8C%E5%9F%BA%E7%9B%A4%E3%80%8D%E3%81%A8%E3%80%8C%E6%9C%80%E6%96%B0API%E3%80%8D%E3%82%92%E7%A9%B6%E3%82%81%E3%82%8B%E2%80%95-Brian-Goetz/dp/4797337206

チケットの履歴

2010/04/12 20:33:49 更新者:ohshima

ご報告有難うございます!
OPEN INTRA-MARTの大島と申します。

ご指摘の通りDCLを行っている理由は高速化を意識してのことです。
im-JavaEE Frameworkが最初にリリースされたときからの実装であり、
当時は高速化のためにこのような実装が行われました。
この実装に関連した問題が発生していないということもDCLを行っている理由です。。

今後synchronized等の方法でもパフォーマンスに違いが無いかを検証して
実装を変更することを検討したいと思います。
ご報告ありがとうございました。

2010/05/06 10:48:54 更新者:imart

この実装に関連した問題が発生していないということもDCLを行っている理由です。

これだけイントラマートが使用されている以上、問題は何件も発生しているでしょう。 スレッドに関する問題なので再現性がなく、問題だということが認識されていないだけではないでしょうか。