Scalaといえば並行処理、並行処理といえばアクター。ということだけど、そこまで大袈裟ではなくサクっとスレッドを起こしたい時はどうしたらよいか。
「プログラミングScala」のP220に「9.4.1 その場限りのスレッド」にopsオブジェクトのspawnメソッドが紹介されています。
import scala.concurrent.ops._ object SpawnExample { def main(args: Array[String]) { println("start") spawn { println("async") } } }
spawnで指定したブロックがスレッドで実行されます。こんなに簡単に書けてよいのか!よいのですw
spawnメソッド内部の擬似コードはこんな感じ。
def spawn(r: => Unit) = { val t = new Thread() { override def run() = r } t.start() }
rは名前渡しパラメータ。rを"名前渡し"ではなく通常の関数リテラルで"値渡し"で記述すると以下のようになる
def spawn(r: () => Unit) = {
しかし、以下のような記述はできなく
spawn( println("abc") )
このような冗長な記述になってしまう。ので、そのまま関数やブロックを渡したい場合名前渡しで行う。
spawn( () => println("abc") )
だから、()をなくした名前渡しパラメータを利用する。
def spawn(r: => Unit) = {
- 作者: Dean Wampler,Alex Payne,株式会社オージス総研オブジェクトの広場編集部
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/01/20
- メディア: 大型本
- 購入: 2人 クリック: 307回
- この商品を含むブログ (38件) を見る
「オブジェクト指向プログラマが次に読む本 Scalaで学ぶ関数脳入門」P104で値渡しと名前渡しの違いについて記述があります。名前渡しは遅延評価ということですね。
値渡しでは、ます引数の式を評価して、関数内の対応する変数をその評価値でパインドします。一方、名前渡しでは、関数の呼び出し時点では引数はまったく評価されず、関数内で参照された時点ではじめて評価されます。複数回参照が行われた場合は、その都度再評価が行われます。
オブジェクト指向プログラマが次に読む本 ?Scalaで学ぶ関数脳入門
- 作者: 株式会社テクノロジックアート,長瀬嘉秀,町田修一
- 出版社/メーカー: 技術評論社
- 発売日: 2010/11/13
- メディア: 単行本(ソフトカバー)
- 購入: 9人 クリック: 285回
- この商品を含むブログ (29件) を見る
concurrentも普通に使えます。
import java.util.concurrent class GetThreadId extends Runnable { def run { println("thread id = " + currentThread.getId) } } val pool = Executors.newFixedThreadPool(5) for (i < - 1 to 10) { pool.execute(new GetThreadId) }