そうめんのMonitorで先読み的なものをつくる
CubaClockのように大量に動画とか音楽を読み込むもの作るときにはそうめん(ThreadLiblary)のMonitorという機能を使うと便利です。
Monitorとは、機能的にいうと、あるものが使えないときは待つ、使えるときはデータ(リソース)を提供するものです。
具体的には、たとえば連続的に画像や音を表示しながら読み込みつづけるようなときに、データが十分にたまるまで待つ、たまったら普通に表示(or再生)、足りなくなったらまた待つ、といった処理を手軽に実現できます。
そうめんのサンプルにロードし続けるThreadと、データを見張るクラスのMonitorを介して、そのデータを使うThreadと間接的に連動するような実装をしたものがあります。
実は、ここの連動感が僕にとってすこしイメージしにくかったんですが、次のように整理すると理解できました。
- まず、Queueというクラスを実装してこれにはデータを入れる配列とMonitorインスタンスを持ちます。
- データを使うThread「A」のメソッド内でQueueを使おうとしたときに配列に利用できるリソースが無ければ、Queue内部のMonitorインスタンスのwaitメソッドを呼ぶため、その瞬間AはそのままそのMonitorの待ちセットに入ります。
このとき他のThreadは関係なく動き続けるので、このQueueに関するロジック(A)だけがロードをまつことになります。 - それとは別に、データをロードするThread「B」が動いていてQueueがたまるとMonitorはnotifyAllをよびだしQueueを待っていたThread(この場合「A」)はすべて処理を再開することになります。
というのを言葉でいうと分かりにくいので図にしてみました
これで、読み込みのサイクルと表示ロジックが別々に動きつつ、Monitorを通じてなんとなく連動するイメージがつかめました。
リソースに対して何かしようとしたThread(Thread.currentThread)が、Monitorによって待ちに入る、というのが僕的にすごく難解でしたが、じつはThread.join()のときと同じ状態です。(joinも内部でjoinMonitorの待ちセットにいれてるだけ)
そうめんは操作面ではみやすいですが、裏で何がどうなってるかみえなくてたまに混乱することがあるので、連動イメージがつかめないときは図にするといいかもしれません。
もうちょっといろいろ感覚的になれていきたいですね。