Enterprise Java Community: Scaling Your Java EE Applications
Java EE アプリケーションのスケーラビリティについて論じた TSS の論文(ってタイトルそのままだな)。キーポイントが簡潔に纏まっていて読みやすい。
以下、要点のメモ。
ロックにまつわる話
ロックの粒度はとにかく小さくしないとスケールさせられない。そのためにはこんなことに注意が必要。
- synchronized ブロックは可能な限り小さくしよう。
- メソッドにキーワード synchronized を付けると暗黙的に「this」がロックされちゃうよ。
- クラスメソッドを synchronized にすると、そのクラスの全てのインスタンスがロックされちゃうよ。
また、Java 5 の java.util.concurrent.atomic に含まれている「ロックしないデータ構造」を積極的に使おう。こいつらは CAS(compare-and-swap)を使うのでロックが必要なくなる。
ブロッキング I/O とノンブロッキング I/O
ブロッキング I/O だと I/O 処理待ち間もスレッドが保持されてしまうので、並行度が上がってくるとリソースを喰う。ノンブロッキングにすれば I/O 処理待ち中にそのスレッドで別の処理が行えるから、必要なスレッド数は少なくて済む。ノンブロッキング I/O なら CPU 数の増加に伴ってスケールするが、ブロッキング I/O だと CPU が増えても性能は頭打ちになる。
シングルスレッド処理の問題
シングルスレッド処理では CPU の数を増やしても性能は上がらないので、並行処理が可能なように処理を組み替える必要がある。JOMP や Parallel Java が使えるけどプログラミングは難しい。