17.7 非同期チャネル

プロセス内通信の基本的な方法には非同期チャネルがあります。その実装では次の単純な連結リストを利用しています。

class LinkedList[A] { var elem: A = _ var next: LinkedList[A] = null }

連結リストへの要素の挿入・追加を助けるために、連結リストの中への参照はすべて、リストの先頭を概念的に表すノードの手前のノードを指します。空きの連結リストはダミーノードで始まり、次の要素は nullです。

チャネルクラスは、送られたがまだ読み出されていないデータを保持するのに連結リストを使います。反対の端では、空きのチャネルから読み出そうとするスレッドは nreaders フィールドをインクリメントすることで自分を登録し、通知されるのを待ちます。

package scala.concurrent class Channel[A] { class LinkedList[A] { var elem: A = _ var next: LinkedList[A] = null } private var written = new LinkedList[A] private var lastWritten = written private var nreaders = 0 def write(x: A) = synchronized { lastWritten.elem = x lastWritten.next = new LinkedList[A] lastWritten = lastWritten.next if (nreaders > 0) notify() } def read: A = synchronized { if (written.next == null) { nreaders = nreaders + 1; wait(); nreaders = nreaders - 1 } val x = written.elem written = written.next x } }