在这个volatile变量示例中,空循环的目的是什么?

时间:2016-01-16 15:29:14

标签: scala concurrency

代码:

while(!found) {}

空循环{{1}}的目的是什么?

3 个答案:

答案 0 :(得分:2)

第一个循环:while (i < p.txt.length && !found)有两个停止条件:搜索空间耗尽或找到匹配时。请注意,found变量用于多个线程:thread {...}可能会生成一个新线程。

因此,线程的循环有多种可能性:

  • 线程找到'!'并设置found。第一个循环中断,第二个循环不执行。
  • 另一个线程设置found。第一个循环中断,第二个循环不执行。
  • 搜索了所有字符。第一个循环中断,第二个循环执行,直到另一个线程找到'!'

第三个可能是你忘记的那个。结果是只有在完成所有循环后才会记录结果。

当然,我无法告诉你为什么代码看起来像这样:每个线程分别打印所有页面的结果,即如果有n个页面,则会记录n^2个结果。此外,所有线程都访问共享对象而不进行同步。如果目标是找到一个感叹号,则代码将失败。无论如何,这些似乎是单独的问题。

答案 1 :(得分:1)

如果看起来像一个忙碌的等待。它将继续检查found的状态,并且在found为真之前执行不会继续。

答案 2 :(得分:0)

根据@Silly Freak的建议,我修改了代码以使用synchronized代替volatile

  object AntiVolatile {
    val pages = for (i <- 1 to 15) yield new Page("!Na" * rand.nextInt(1000) + " Batman!", -1)
    var found = Some(false)

    def run(): Unit = {
      for (p <- pages) yield thread {
        var i = 0
        var foundInThread = found.get
        while (i < p.txt.length && !foundInThread)
          if (p.txt(i) == '!') {
            found.synchronized {
              found match {
                case Some(true) => foundInThread = true
                case Some(false) => {
                  p.position = i
                  found = Some(true)
                  Thread.sleep(1)
                }
                case _ =>
              }
            }
          } else i += 1
        // if still not found, wait for another thread to find it.
        def wait(): Unit = {
          found match {
            case Some(false) => wait()
            case _ =>
          }
        }
        wait()
        log(s"results: ${pages.map(_.position)}")
      }
    }
  }

没有更多的数据竞争:

Thread-29: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-27: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-28: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-26: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-30: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-31: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-32: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-25: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-33: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-34: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-39: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-38: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-37: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-36: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-35: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)