読書会(JAVA CONCURRENCY IN PRACTICE)第6回議事録

[ 戻る ]


日時:12/9 10:00〜17:00
場所:高津区市民会館 第4会議室
出席者:中島、岩室、大石、高橋(徹)、遠藤、村山、内脇、小松、高橋(智)、吉本、小棚木、根元、石黒、鈴木 8-1(和訳p190、原書p167〜168)
スレッド拘束(Thread confinement)…あるタスクにアクセスできるのは1つのスレッドのみ。
スレッドプールが最も効率的なのは等質で独立なタスク
(例)書類作成(3日)→ハンコ(30秒)を並行して行っても意味があまりない。あまり高速化されない。
スレッド拘束を使うタスクは勝手にスレッド数を増やせないので、そのことをドキュメント化したほうがよい。
8-1-1(和訳p191、原書p168〜p169)
スレッドの飢餓状態デッドロックを解決するためにはスレッドプールのサイズを増やしてもダメな場合がある。
未実行タスクが実行中のタスクを待っている
・スレッドプールのサイズを増やせば、とりあえず実行が始まる。しかし、スレッド数がもっと増えてしまってまたデッドロックになる可能性もある。
・タイムアウトを設定して実行中のタスクを終了させる。
・タスクの投入時にもう実行できないというエラーにする。タスクによっては致命傷になってしまう?
・スレッドプールの長さを可変長にして調整できるようにする。
1つのJDBCコネクションを複数スレッドで使いまわすのはNG。
リスト8.1(和書p192、原書p169)
コードの全体像がこれだけではわからない。
どこでデッドロックするのか?自分自身もシングルスレッドだから?
8-2(和書p193〜194、原書p171)
Runtime.availableProcessors()が使用できるようになったのは1.4から
1.1や1.2ではCPUが複数あっても1つのCPUしか使用できないバグがあったが、改善された。
ハイパースレッド…OSにスレッドが2つあるように見える場合は?
N+1 threadsとあるが、N=1の場合の動きはどうなるのか?
Wait時間が長い場合W/Cが大きくなる。→スレッド数が増加する。
8-3-1
脚注3について(和書p195、原書p172)
SynchronousQueueを使用していない場合について記述されている。
キューが満杯になっていない場合…キューにタスクを投入して終了。スレッドは作成されない。
キューが満杯になっている場合…スレッドが作成され、タスクの実行が始まる。
コアサイズがゼロの場合、タスクがないとスレッドは廃棄される。
コアサイズがノンゼロの場合、スレッドは廃棄されない。
8-3-2(和書p196、原書p172)
リクエストに応じてスレッドを作成すると、負荷が高いときの処理がスレッド作成の分だけかえって遅れてしまう。
OSの制約でOutOfMemoryErrorが発生すると、そのスレッドは落ちる。メモリ資源を使い果たしているので他のスレッドにも悪影響が出る。
ただし、ガベージ・コレクションのスレッドは落ちないはずである。
セキュリティーマネージャーはTomcatではデフォルトでオンになっている。
リスト8.8(和書p202、原書p179)
なぜ最初からThreadPoolExecutorでnewしないのか?あとからdowncastしているのはお行儀がよくないのでは?
リスト8.11(和書p206、原書p182)
最後1つだけが末尾再起している。
resultsにどのような順番でaddされているかがわからない。したがって、結果の順番が正しいかどうか保証されない。
順番を保証するためにはArrayList等を使用しなければならない。
リスト9.6(和書p222、原書p223)
和書と原書で食い違いのある部分がある。
if(Thread.isInterrupted)
if(Thread.currentThread().isInterrupted())
if(runningTask != null)が2回出てくるが、最初のほうが食い違っている。
if(runningTask == null)
if(runningTask != null)
もしif(runningTask == null)で記述すると、2回目以降はnot nullになっているので、1回のみ実行ということになる。
リスト9.8(和書p225、原書p200)
最後のほうの以下の部分は誤りではないか。
(誤)backgroundExec.execute(task);

(正)(誤)backgroundExec.execute(listner.task);
リスト10.3(和書p235〜236、原書p209)
ハッシュコードが一致する場合はあるか?
オブジェクトがガベージ・コレクションによって移動された場合はありうる。
JVMが生きている限り同じオブジェクトに対しては同じハッシュコードが返ってくる。
リスト10.4(和書p237、原書p210)
宿題:あなたは何秒でデッドロックしましたか?ただし、ハッシュコードを覚えておくためにはDBが必要。
リスト10.5(和書p238、原書p212)
setLocationがnotifyAvailableをコールしているため、Dispatcherのロックを取得する。
getImageがgetLocationをコールしているため、Dispatcherのロックを取得する。
したがって、デッドロックの危険性がある。
10-1-4(和書p238、原書p212)
脚注3の意味があいまい。
リスト10.6(和書p240、原書p214)
HashSetで取得している順番で場所を取ってくるので、for文が回っている間に動いてしまう。
→位置がずれないのはどうやっても無理なのでは?タクシーに止まってもらうしかない。
10.2(和書p243、原書p215)
バイトコード分析は商用ツールで可能。
リスト10.7(和書p244、原書p217)
この例では同じコネクションを複数のスレッドが共有してしまっている?→これでは動かない。
10-3-2(和書p246、原書p218)
脚注5
原則Thread.yieldは使用しないほうがよい。
10-3-3(和書p247、原書p219)
イーサネットでの送信の衝突の例が記述されているが、イーサネットの規格が変化したこと、ハブを利用した全二重の通信が一般的であることから、このような事態はもう発生しなくなってきている。無線LANの世界ならありうるが。


[ 戻る ]