Reputation: 189
I am learning to write code in multi-threading. I understand the literal meaning of synchronized operator in Scala. But, when I run the following code, I do not understand the output.
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;
}
}
with synchronized in put and get, the function would continue forever, which is expected. But, when I remove the synchronized from the definition, the output will be
In put.
In put.
In get.
In get.
Could Anyone explain why the results look like this? Thanks a lot.
Upvotes: 0
Views: 94
Reputation: 33029
The JVM's memory model has no guarantees for sequential consistency if you don't use something like volatile
or synchronized
. This means that each thread essentially has an independent view of the current value of n
.
My guess is that something like this is happening:
put
twice and gets stuck waiting (I guess N=2
?)n=2
get
twice, bringing n
down to 0, and gets stuck waitingn
, and it never changes—they just stay stuck in the while
loopsTry making n
volatile and see what happens. (I don't that will give you 100% correct behavior, but I don't think it will get stuck either.)
Upvotes: 1