HashMapのマルチスレッドアクセス問題 - getに対する同期化は忘れがち?
HashMapのマルチスレッドアクセス問題は、これまで色んな記事やBlogで取り上げられてますのでかなり有名ですよね。例えば以下とか。
複数のスレッドから同時にputされると、無限ループになる可能性があるというやつですね。
しかしgetに対しても同期化が必要という意識はもしかして低いのでしょうか?
これまでいくつかのプロジェクトで同様のバグに出会ってきました。皆さん、getやremoveに対してはちゃんとsynchronzedブロックを使うなどして同期化を行っているんですけど、getには何もせず。
この場合、putとgetが重なると値が存在してもnullが返ることがあります。結果として予期せぬ動作を起こしてしまいます。
そして最近多いのが、ハードだけ入れ替えたらこの手の問題が突然起き出したというケースですね。昔のサーバであれば一度も起きなかった場合でも、最近のマルチコアのCPUだと起きやすいようです。なのでハードだけ入れ替えという時も、一度アプリケーションを見直した方が良いかもしれませんよ。。。
また、ミドルウェアも同様にこのHashMapの同期化のバグを持っている場合もあります。例えばこれとか。ちょっと古いですがJBoss3/4系でJMS使っている人は要注意じゃないかな。