torutkのブログ

ソフトウェア・エンジニアのブログ

Java読書会「Java並行処理プログラミング」を読む会

本日はJava読書会の日でした。
Java互助会時代からを含めると1998年12月に開始してから今月でちょうど8周年になります。ほぼ毎月1回のペースで今に至っています。次回は1/20予定。

前回までは、洋書"Java Concurrency In Practice"を分担翻訳して朗読していましたが、先月翻訳本が出版されたので今月からは翻訳本の方を朗読する形で進めました。

Java並行処理プログラミング ―その「基盤」と「最新API」を究める―

Java並行処理プログラミング ―その「基盤」と「最新API」を究める―

ズームインJava

本編の「Java並行処理プログラミング」の前に1時間(朝9:00〜10:00)だけ、「エンタープライズアプリケーションアーキテクチャ」を読んでいます。ズームインJavaと称して、課題図書投票で次点になった本などが対象となっています。

進め方についてどうするか前回議論になりましたが、事前準備なし、時間が短いので朗読ではなくキーワードを拾い読みしながら進めることにしました。

今日読んだ「エンタープライズアプリケーションアーキテクチャ」の部分は、Webアプリケーション、並行性の箇所ですが、なんでこの本がよいと話題になるのか理解に苦しむ、著者のうんちく(能書き)断片的にだらだら書き下し状態で、なんだか・・・というインプレッション。
また、珍訳(軽オフラインロック、重オフラインロック、緩ロック)が話題に・・・。

本編

開始時10人前後、午後になって14人の参加者となりました。
今回は8章から朗読開始です。8章スレッドプール、9章GUIアプリケーション、10章生存事故を防ぐ、までです。
朗読者(今回は4人)が交代で朗読し、随時議論を挟みながら進めていきました。

最適なスレッド数に関する式が興味深い。CPUバウンダリなタスクなら"CPU数+1"、一般的には下記の式で出すとある。

 T = N * U * ( 1 + W/C )
 N:CPU数、U:CPU稼働率、W/C:ウェイト時間と計算時間の比率、
 T:プールのスレッド数

Executorフレームワークが生成するスレッドプールはSingleThreadPoolを除き、ThreadPoolExecutorのサブクラスとなりますが、このコアプールサイズ属性とキープアライブ時間を調整することでいろいろなスレッドプールのポリシーが実現できます。

キューについては、かならずキューあふれの問題がありますが、今回その問題についても述べられており(飽和ポリシー)、実践的な設計において役立つ知識が得られました。

難しい話題もあり、例題(8-11)の末尾再帰はfor文の繰り返し処理の中にあるので本当に末尾再帰になるのか?といった解がでない議論も行われました。議論としては、for文がループ展開された場合に最後の1つだけ末尾再帰になるのでは?といった解釈案が出たものの、真意は不明のままです。
パズルの例は、ちょっと理解難しく、さすがの読書会でも手こずる骨のある内容でした。

GUIはなぜシングルスレッドか? の節では、マルチスレッドGUIツールキットが難しい理由が紹介されており、なるほどと頷ける内容。

デッドロックの箇所では、各自宿題として例題プログラムを実行してどれだけの頻度で発生するかを確認することになりました。
なお、僕のPC(ノートPC)では、数秒でデッドロック発生します。デッドロックが発生した状態で、JVMのスレッドダンプを出力させると、確かにデッドロックが発生したとあります。
Windowsマシンでは、Ctrl-Breakを押すと出力させられます。UnixはSIGQUITシグナルまたはCtrl-\だそうです。
以下スレッドダンプから抜粋。

Found one Java-level deadlock:
=============================
"Thread-19":
  waiting to lock monitor 0x02abe3e4 (object 0x22ac0288, a Account),
  which is held by "Thread-13"
"Thread-13":
  waiting to lock monitor 0x02abe584 (object 0x22ac0348, a Account),
  which is held by "Thread-17"
"Thread-17":
  waiting to lock monitor 0x02abe2ac (object 0x22ac01b8, a Account),
  which is held by "Thread-19"

なお、今日の一つだけ覚えておくことは、「オープンコールを使おう」です。
P.241囲みブロック引用

 プログラム全体を通じてオープンコールを使うよう、努力してください。オープンコールを遵守しているプログラムは、ロックを保持した状態でよそ者メソッドを呼び出しているプログラムに比べて、デッドロックの可能性に関する分析がきわめて容易です。

打ち上げ

雨天なので、会場の高津市民館から外に出ないで移動できる隣のビル(Nocty1)のレストラン街にある溝の口ビアホールで実施。ジャンボオムレツ/焼きそば/パスタと腹のふくれるものとドイツビールで盛り上がりました。