[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 10924] Re: Doug Lea 本



高橋(徹)です。

   "The Murayama <locutus@xxxxxxxxxxxxxxxx>"さんは書きました:
> ここしばらくDoug Leaの「Javaスレッドプログラミング」を読んでた
> のですが,本当にこれを理解した人っているんでしょうか?
> 
> この本は並列プログラミングの経験者にだって理解するのは困難です.
> ましてやそうでない大多数の(ベテランプログラマーを含む)未経験者
> が理解するのはほとんど不可能な気がします.
本の書き方として、頭から読み下していって1パスで理解できるような
構成にはなっていないのは確かです。読書会時もそのあたりが問題と
なっていました。本の構成の問題として理解が難しいということが
あります。読書会でも途中で復習編の回を設けたほどでした。ただ、
そのときの効果は今ひとつだったような。。。


結城さんが、「Java言語で学ぶデザインパターン入門 マルチスレッド編」
という書籍を出しています。目を通していないのですが、こっちはかなり
易しいのではないでしょうか。

> これをマルチスレッドプログラミングの本と思って買うと当てが
> 外れることになりますね.実際には並列プログラミングの本でさえ
> ないようですが.
「マルチスレッドプログラミング」というと、何を扱っているべきなの
でしょうか? 当てが外れるというからには何かしら期待している内容
があるのでしょうね。期待とずれていたからでしょうか?

[ばさっと略]

> ○並列処理のハードウエアの解説が少ない,或いはない.
> Cache Coherency Protocolの解説もなかった気がします.
> 
> volatileやsynchronizedが,実際にネイティブコードレベルでどの
> ように実現されているのかという話も出てません.
メモリモデルの話までは出ていました。それより以下の部分については
"in Java"の範疇を逸脱するし、モデル化という抽象を行ったのに具象に
戻ることになるので、無くてもよいと思います。
余談としてvolatileが実装されているVMがない(少ない?)、といった
情報はあってもよいかなと思いますが、あくまで余談で留めるべきかと。

> この辺の話を理解していないと,本当の意味で効率の良いプログラムを書くのは
> 難しいと思います.
ここの「効率の良い」はパフォーマンスが良いの意味でしょうか?
普段パフォーマンスをあげるためにマルチスレッドを使うという設計選択
をしていないので、あまり意識していませんでした。通信で送受信を別々
にして、それぞれの処理の記述をシンプルにする、といった局面でマルチ
スレッドを使用しています。

[ばさっと略]

> これらのバグには,デバッガもprint文さえも役に立つという保証は全く
> ありません.だからこそ「少しでもデバッガが使えるように設計する」
> というのが,いわばベストプラクティスになっていると思います.
マルチスレッド下ではデバッガを使うことによっても条件が変わるので
設計段階で検証するしかないのではないかと考えます。

> 同期なんかも同様で,同期のデバッグのし難さはJSP以上と言っても良いでしょ
> う.だからこそできるだけ多くの部分を同期から切り離して「普通のJava」にカ
> プセル化しておけばJUnitでテストできますし,デバッガも使おうと思えば使え
> ます.テストのやりようのない「普通ではない/同期関係のJava」を最小限にし
> ておけば,バグが出ても対応は比較的簡単です.
デバッガを使うのはシングルスレッド部分、という意図でしたか。
この考え方はいいですね。
マルチスレッドを考慮した設計手法に、ROOM、OCTOPUSといったオブジェクト
設計手法があります。ちょっとかじった程度ですが、どちらにもやはり
マルチスレッドな部分とそうでない部分を分離することが含まれています。
# Boochさんクラスになると、わざわざこんな拡張せずに標準のUMLで十分
# 表現(設計)できるとのこと。

> ○リファクタリングはリファクタリングではない.
> 同期処理のリファクタリングみたいな項目もありますが,おそらくあれは
> リファクタリングではありません.
書籍「リファクタリング」では、明確にマルチスレッドを対象外とする
ことが明記されています。

> まず第一に,同期処理の変更はプログラムの挙動が変化を伴います.リファクタ
> リングは挙動を変化させずに綺麗に書き直すことのはずです.
「挙動を変化させずに」とは言ってなく、「外部から見た振る舞いを保ったま
ま」と書籍[リファクタリング」では言っていたと思います。「挙動を変化さ
せずに」では外部・内部の視点がぼやけてしまいます。

> て同期の変更はアルゴリズムの変更を意味するし,大域的な影響を排除すること
> もできません.それこそ,ほんの一行コードを書き加えただけで挙動が一変する
> こともあります.これはリファクタリングの趣旨に反するものです.
アルゴリズムの変更は外部的振る舞いが変わらないのでリファクタリングの範
疇でしょう。外部的振る舞いが変わってはアルゴリズムの変更というより仕様
の変更でしょう。
大域的な影響(悪影響)は、バグによるものなのでリファクタリングの趣旨に
反するというのではなく、リファクタリング時に混入したバグでしょう。
書籍「リファクタリング」ではテストによってバグの混入を極力防ごうと
していますが、マルチスレッド環境ではテスト以外の手法を用いてバグ混入を
防ぐことが必要とされます。

> 第二に,同期処理はテストが構築できません.微妙なタイミングはそもそもテスト
> 不可能ですし,そうでなくともテスト自体が挙動を変更させる可能性を排除できま
> せん.(ほとんど不確定性原理の世界.観測すること自体が状態に変更を加える
> 行為だから,元の状態を知る術はない.)十分なテストなしのリファクタリングは
> 無謀な試み意外の何物でもなく,既にリファクタリングとは言えない代物でしょう.
前半は同意、後半は異論ありです。
テストではバグのないことは保証できません。たまたまテストしたケースで
バグが見つからなかったことしか言えません。また、完全なテストをするには
無限に近い組み合わせを網羅せねばならず現実的ではありません。
テストだけで、それも限られた数のテストケースでリファクタリングをする
ことも無謀な試みです。XP(eXtreme Programming)では、ペアプログラミング
による他者の検証・検査が行われているからのリファクタリングなので、単に
テストしたから良し、ということではないはずです。
マルチスレッドの場合、テストに頼れない分、設計段階で検証するしかないの
かと思います。リファクタリングはマルチスレッドの場合は再設計(と再検証)
になると。

> 結局,同期部分だけはリファクタリングが不可能なので,最初に綺麗に設計し,
> 後からの変更は最小限に押さえるべき,ということになります.
同期の粒度を小さくするというリファクタリングは可能ではないかと思います。
書籍にも、リスト構造における同期の例が確か載っていました。

[ばさっと略]

> 経験が無い限り「難解だ/理解できない」とは感じても,「間違っている」
> ことや,「この本には並列プログラミングの重要な部分が,すっぽり抜け
> 落ちている」ことなどは分からない.
そうです。
「Javaスレッドプログラミング」で抜けている重要な部分や、間違っている部
分を提示してもらえると嬉しいですね。

--
TAKAHASHI Toru
torutk@xxxxxxxxxxxx