难以理解同步定义

时间:2013-07-03 14:50:48

标签: multithreading scala synchronized

我正在学习用多线程编写代码。我理解Scala中synchronized运算符的字面含义。但是,当我运行以下代码时,我不理解输出。

package examples
import scala.concurrent.ops._

object concurrent extends App {

    class BoundedBuffer[A](N:Int) {
        var in = 0;
        var out = 0;
        var n = 0;

        def put(x:A) = synchronized {
          while(n>=N)
            wait()
          in = (in + 1)/N;
          n = n+1;
          println("In put.")
          if(n==1)
            notifyAll()
        }

        def get = synchronized {
          while(n==0)
            wait()
          out = (out + 1)%N;
          n = n-1;
          println("In get.")
          if(n == N-1)
            notifyAll()
        }
    }

    val buf = new BoundedBuffer[Int](10)
    spawn {
        while(true)
            buf.put(0);
    }
    spawn {
        while(true)
            buf.get;
    }
}

在put和get中同步,该函数将永远持续,这是预期的。但是,当我从定义中删除synchronized时,输出将是

In put.
In put.
In get.
In get.

有人可以解释为什么结果看起来像这样吗?非常感谢。

1 个答案:

答案 0 :(得分:1)

如果您不使用volatilesynchronized之类的内容,则JVM的内存模型无法保证sequential consistency。这意味着每个线程基本上都具有n的当前值的独立视图。

我的猜测是这样的事情正在发生:

  1. 第一个线程产生
  2. 第一个线程运行put两次并等待等待(我猜N=2?)
  3. 第二个线程产生,获取n=2
  4. 的当前视图
  5. 第二个线程运行get两次,将n降为0,等待等待
  6. 由于这里没有同步构造,每个线程都维护其n值的私有视图,并且它永远不会改变 - 它们只会停留在while循环中
  7. 尝试制作n volatile,看看会发生什么。 (我不会那样会给你100%正确的行为,但我认为它也不会被卡住。)