我正在学习用多线程编写代码。我理解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.
有人可以解释为什么结果看起来像这样吗?非常感谢。
答案 0 :(得分:1)
如果您不使用volatile
或synchronized
之类的内容,则JVM的内存模型无法保证sequential consistency。这意味着每个线程基本上都具有n
的当前值的独立视图。
我的猜测是这样的事情正在发生:
put
两次并等待等待(我猜N=2
?)n=2
get
两次,将n
降为0,等待等待n
值的私有视图,并且它永远不会改变 - 它们只会停留在while
循环中尝试制作n
volatile,看看会发生什么。 (我不会那样会给你100%正确的行为,但我认为它也不会被卡住。)