読んだ: Java 並行処理プログラミング / ブライアン・ゲーツ、ダグ・リー、他 著、岩谷宏 訳
Java の並行処理プログラミングについての書籍を読みました。 2006 年の本なので結構古いですが、内容的には今でも十分通用するものですし、世間からも高く評価されてるみたいですね。 内容的にはかなり良かったです。
Java並行処理プログラミング ―その「基盤」と「最新API」を究める―
- 作者: Brian Goetz,Joshua Bloch,Doug Lea
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2006/11/22
- メディア: 単行本
- 購入: 30人 クリック: 442回
- この商品を含むブログ (170件) を見る
内容紹介
簡単に内容を紹介します。 本書は全 4 部、16 章構成となっています。
序章
まず、第 1 章は序章ということで、並行処理の歴史と、マルチスレッドプログラミングの必要性や、利点と欠点などが述べられています。 IO 待ちすることが多い処理を複数実行する場合は、マルチスレッドにすることで CPU 資源を無駄にしない、とか、GUI プログラミングの場合は基本的に GUI 部品を触るのは 1 つのスレッドのみからで、他の時間のかかる処理などは別のスレッドで実行するようになっているから自然とマルチスレッドになるとか、そういう話です。 欠点としては、当然のことながらソフトウェアの複雑性が上がる、という感じです。
第 1 部 基礎編
続く 2 章からは第 1 部 「基礎編」 です。
第 2 章 「スレッドセーフ」 では、ソフトウェア部品をスレッドセーフに作らなければいけない理由や、どのようにすればスレッドセーフになるかの説明がされます。 例えば、オブジェクトの状態を複数のスレッドで共有しなければ良い、とか、複数のスレッドで状態を共有する場合は、その状態をロックでガードする、とかですね。 処理のアトミック性や生存と実行性能についても説明があります。
3 章 「オブジェクトを共有する」 では、可視性の説明や揮発性変数 (volatile
変数) について、それから不可変性 (final
修飾) についてやオブジェクトを安全に公開する方法についてなど説明されています。 可視性の概念は Java を触り始めた人は知らないことも多いと思うので結構重要ですね。
4 章ではスレッドセーフなクラスを設計する方法や、スレッドセーフでないクラスをスレッドセーフに使用する方法 (スレッド拘束にするとか) などが述べられています。 同期化のポリシーをちゃんとドキュメント化せよ、というようなことも書かれています。 (個人的にはドキュメント化されていなければスレッドセーフではないとみなすべき、と思ったりします。)
5 章では Java API に含まれる並行処理プログラミングのための様々なクラスが紹介されます。 主には Java SE 5 で導入された java.util.concurrent
パッケージに含まれるものです。
第 2 部 並行アプリケーションの構造を作る
6 章から 9 章までが第 2 部です。 ここでは、アプリケーション全体 (あるいはある程度まとまったアプリケーションの部分) の並行処理について述べられます。 ざっくりと書くと次のような話があります。
- どういう部分を並行処理にすべきなのか
- 実行されるタスクとスレッドの管理は別に行うべきであるという話 (スレッド管理は Executor を使って行う)
- スレッドの所有者が誰なのか、設計上明確にしておくべき
- タスクはキャンセル可能にすべきであり、Executor はシャットダウン可能にすべきである、という話
- Java のスレッドには
interrupted
状態がある
- Java のスレッドには
- スレッドプールを使う
- GUI プログラミングとシングルスレッド設計について
ここら辺はアプリケーション全体の設計に絡んでくるところなのでなかなか難しい領域ですし、読みごたえがありました。
第 3 部 生存、実行性能、試験
10 章から 13 章までは、生存についてや実行性能、試験といったソフトウェアの品質についての説明です。
並行処理がある場合、デッドロックによりソフトウェアの処理が止まってしまうという可能性があります。 できるだけ、ロックを保有せずにメソッドを呼び出す 「オープンコール」 を行うように気を付けることで、デッドロックしないコードを書きやすくなります。 また、資源が無限にある場合は問題ないようなコードになっていても、実際上は資源が有限で、資源の枯渇によって飢餓状態になって処理が止まってしまうこともあります。 スレッドプールのスレッド数に制限があって、スレッドプールで動いているタスクが、スレッドプールの待機列にあるタスクの処理を待っていて処理が止まる、なんていう場合も紹介されていて、なかなか難しいなーという感じです。
11 章、実行性能についての章では、コンテキストスイッチが多いと並列化しても実行性能が上がらない可能性があるとか、ロックの粒度を小さくすると良いとか、そういう話が書かれています。 Java API に含まれているスレッドセーフなコレクションクラスは、かなり性能がいいのでそっちを使うようにすべき、とか。
12 章では並行処理のテストについて述べられています。 そもそも並行処理のテストは難しいとか、Java には JIT があるので性能評価しづらいとか、そういう感じです。 あとは計測のための処理がスレッド間の同期化に繋がってしまうことがあって、その場合並行処理のテストがちゃんとできないわけなので気を付ける必要があるとか、まあ難しいですね。
感想
Java の並行処理についてよくまとまっています。 ここまでまとまってる書籍は他にないように思いますので、古いことは古いですが、Java で並行処理を書くなら読んでおくといいでしょう。 (そして Java を使うのに並行処理をしないなんてことはほとんどないと思うので、まあ Java を書く人は全員読んでおいていいんじゃないですかね。) 内容的には文句なしです。
Android アプリ開発なんかでもマルチスレッド処理が必要になる場面が多いですので、Android アプリの開発者も読んでおくと良さそうです。
一方で、話の展開についてはちょっと微妙かなぁという気になります。 展開が冗長なところが多く、結論に達するまでだめな例がいくつも出てくるなんてことがあるので、読んでいてもどかしい気持ちになることが多かったです。 しかし逆に、並行処理プログラミングについてあまり知識がない状態ならば、そういう展開なのは理解の助けになるかもしれません。
他の書籍の紹介
並行処理に関して私が読んだことのある他の書籍も紹介しておきます。
Java 言語で学ぶデザインパターン入門 マルチスレッド編
増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編
- 作者: 結城浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2006/03/21
- メディア: 大型本
- 購入: 15人 クリック: 287回
- この商品を含むブログ (203件) を見る
『Java 並行処理プログラミング』 と比べ、内容は易し目です。 図なども多く、わかりやすいです。 並行処理について (他言語でも) あまり経験がないのであれば、『Java 並行処理プログラミング』 よりも先にこちらを読むといいでしょう。
ただ、java.util.concurrent
パッケージの説明が付録にあるだけであり、低級 API が多く使われているので、勉強には最適ですが実用的かというと微妙かもしれません。 この書籍で並行処理について勉強したうえで、実用的な内容は 『Java 並行処理プログラミング』 の方で学ぶ、という流れが良さそうです。
並行コンピューティング技法
並行コンピューティング技法 ―実践マルチコア/マルチスレッドプログラミング
- 作者: Clay Breshears,千住治郎
- 出版社/メーカー: オライリージャパン
- 発売日: 2009/12/21
- メディア: 大型本
- 購入: 12人 クリック: 598回
- この商品を含むブログ (38件) を見る
並行処理の基礎的な話と、アルゴリズムの話が主です。 言語に依らない並行処理の全般的なところを知りたいなら読むといいかもしれません。
その他の書評
- 良いプログラマを目指すなら「Java並行処理プログラミング」は今すぐ読むべき - Higepon’s blog
- 『僕はこの本を読んで、Java の並行処理プログラミングは、想像を遙かに超えて進化している事に驚きを隠せなかった。何回も twitter で Java すげーと叫んだ。 / これを読んでしまうと、最近僕が熱心な Scheme も含めて、自分の身の回りにあるプログラミング言語は、全く並行処理の事を考えていない事に気付かされる。プログラマとして、大変な危機感を持った。』 とのこと。
- 私も Java のスレッド周りは良くできてると思います。 他言語だと Actor モデルとかあって、そっちはそっちで並行処理に有利っぽかったりもするので、スレッド周りが良くできてるから並行処理しやすい言語だとはかならずしも言えないとは思うけど、まあスレッド使うのはベタな感じで書きやすいですよね。
- のびーの食っちゃね〜だらだらな日々。食っちゃ寝生活してても意外と平気だったりする。 : 「Java 並行処理プログラミング」を読み終わりました。
- Java並行処理プログラミング - kagamihogeの日記
- 『Javaの並行プログラミングはだいぶ身近なものになったとはいえやはり伝家の宝刀チックだな、というのが俺の印象です。抜かずに済めばそれでよし、しかし抜いた時には覚悟を決めて使いこなさないといけない、みたいな』
- 何でもかんでも並行処理すればいいってものではないし、確かに使わなくて済むならそれでいいですよね。 とはいえある程度の規模のアプリケーションならたいてい何かしら並行処理は必要なので、最低限の知識は持っておく必要がある気がします。
- Java並行処理プログラミング - 理系学生日記