ScalaのThreadとRunnable

Threadクラス

Threadクラスを利用すれば、並行処理を行うことができます。

object Main extends App {
  println(1) 

  // 別のスレッドを生成
  val thread = new Thread(() => {
    println(2)
    Thread.sleep(1000)
    println(3)
  })
  // 実行
  thread.start()

  println(4)
}
1
4
2
3

new Thread(() => { ??? })の() => { ??? }部分は、new Runnable { override def run() = ??? }と内部的に同じ意味になります。
これはRunnableトレイトをミックスインした匿名クラスをインスタンス化しています。匿名クラスはrunメソッドをオーバーライドしています。 Runnableトレイトは後述します。

Threadクラスの継承

Threadクラスを継承し、runメソッドをオーバーライドしたクラスを利用することでも並行処理が可能です。

class ThreadSample extends Thread {
  override def run() = {
    for (i <- 1 to 100) println(Thread.currentThread().getName, i)
  }
}

object Main extends App {
  for (i <- 0 to 4) (new ThreadSample).start()
}
Thread-3, count: 1
Thread-4, count: 1
Thread-0, count: 1
Thread-1, count: 1
Thread-2, count: 1
Thread-1, count: 2
Thread-0, count: 2
Thread-4, count: 2
// 以下、4つのスレッドが100までカウントするのが続く

Runnableトレイト

Threadクラスを継承する方法では他のクラスを継承できません。そんなときはRunnableトレイトをミックスインします。
この場合、new Threadの引数にRunnableをミックスインしたクラスのインスタンスを渡します。

class ThreadSample extends Runnable {
  def run() = {
    for (i <- 1 to 100) println(Thread.currentThread().getName, i)
  }
}

object Main extends App {
  for (i <- 0 to 4) (new Thread(new ThreadSample)).start()
}

ちなみに抽象メソッド(処理本体が書かれていないメソッド)をオーバーライドするときは、overrideは必要ありません(もちろんoverride def run() = ???としてもかまいません)。