为什么在这种情况下不能简单地加入工作?

时间:2016-04-21 15:16:53

标签: scala concurrency

我正在学习并发性并编写了一些代码来证明Scala中的交错。但是,即使使用join语句,count仍保持为0。谁能告诉我我在这里缺少什么?

object Main extends App {
  new Worker().doWork()
}

class Worker {
  private var count = 0
  def doWork() = {
    val t1 = new Thread{new Runnable {
      override def run(): Unit = {
        (0 to 10000).foreach {_ => count = count + 1}
      }
    }}
    val t2 = new Thread{new Runnable {
      override def run(): Unit = {
        (0 to 10000).foreach {_ => count = count + 1}
      }
    }}
    t1.start()
    t2.start()

    t1.join()
    t2.join()
    println(s"Thread: ${Thread.currentThread()} - $count")
  }

}

2 个答案:

答案 0 :(得分:9)

主要问题是您使用Thread(花括号)而不是{}(括号)在() s的定义中创建匿名类。基本上,您只是在Runnablet1个线程的构造函数中实例化t2个对象。换句话说,您使用简单的Thread()构造函数而不是Thread(Runnable r)构造函数。

val t1 = new Thread { // this is the issue
  //creating anonymous class extending Thread
}

您应该使用:

   val t1 = new Thread( // opening parenthesis
      new Runnable {
        override def run(): Unit = {
          (0 to 10000).foreach {_ => count = count + 1}
        }
    })                  // closing parenthesis 

答案 1 :(得分:0)

一旦你修复了使用{}而不是()为Thread构造函数引起的问题,你会看到计数的明显随机值。

原因是你同时启动两个线程,并且t2将在对t1的连接调用之前开始计数(并且不能保证它不会继续运行,只有主线程将等待t1)。

如果您要更改流程以启动线程1,加入它,启动线程2,加入它,您将得到结果20002保证,但如果您同时运行两个线程,结果是随机的。