scalaz MVar take 方法无限阻塞
scalaz MVar take method blocks infinitely
我是 scalaz 的新手,我想探索 MVar 的用法。所以我做了一个小脚本:
object MVarThingy {
val haha = newEmptyMVar[Int]
def forkIO(f: => IO[Unit])(implicit s: Strategy): IO[Unit] = IO {
s(f.unsafePerformIO)
}
def writeDelay(v: MVar[Int]): IO[Unit] = for {
_ <- IO(println("wait to put value to haha"))
_ <- IO(Thread.sleep(5000))
_ <- IO(println("now put value to haha"))
_ <- v.put(42)
} yield ()
def writeNow(v: MVar[Int]): IO[Unit] = v.put(24)
def takeHaha: IO[Int] = for {
v <- haha
_ <- IO(println("try to get haha.."))
a <- v.take
} yield a
def run(): Unit = {
val blah = for {
mvar <- haha
_ <- forkIO(writeDelay(mvar))
a <- takeHaha
} yield a
println("value in mvar is: " + blah.unsafePerformIO)
}
}
如果我运行MVarThingy.run
,它会无限阻塞。
但是,如果我将 takeHaha
和 run
更改为
def takeHaha(v: MVar[Int]): IO[Int] = for {
_ <- IO(println("try to get haha.."))
a <- v.take
} yield a
def run(): Unit = {
val blah = for {
mvar <- haha
_ <- forkIO(writeDelay(mvar))
a <- takeHaha(mvar)
} yield a
println("value in mvar is: " + blah.unsafePerformIO)
}
然后一切如我所愿,输入值后,将取值,程序将正常终止。
能否解释一下为什么会有这样的差异?
我刚刚发现 newEmptyMVar[A]
会产生 IO[MVar[A]]
,而 IO[A]
是懒惰的。
在第一种情况下,我得到两个不同的 MVar
。
我是 scalaz 的新手,我想探索 MVar 的用法。所以我做了一个小脚本:
object MVarThingy {
val haha = newEmptyMVar[Int]
def forkIO(f: => IO[Unit])(implicit s: Strategy): IO[Unit] = IO {
s(f.unsafePerformIO)
}
def writeDelay(v: MVar[Int]): IO[Unit] = for {
_ <- IO(println("wait to put value to haha"))
_ <- IO(Thread.sleep(5000))
_ <- IO(println("now put value to haha"))
_ <- v.put(42)
} yield ()
def writeNow(v: MVar[Int]): IO[Unit] = v.put(24)
def takeHaha: IO[Int] = for {
v <- haha
_ <- IO(println("try to get haha.."))
a <- v.take
} yield a
def run(): Unit = {
val blah = for {
mvar <- haha
_ <- forkIO(writeDelay(mvar))
a <- takeHaha
} yield a
println("value in mvar is: " + blah.unsafePerformIO)
}
}
如果我运行MVarThingy.run
,它会无限阻塞。
但是,如果我将 takeHaha
和 run
更改为
def takeHaha(v: MVar[Int]): IO[Int] = for {
_ <- IO(println("try to get haha.."))
a <- v.take
} yield a
def run(): Unit = {
val blah = for {
mvar <- haha
_ <- forkIO(writeDelay(mvar))
a <- takeHaha(mvar)
} yield a
println("value in mvar is: " + blah.unsafePerformIO)
}
然后一切如我所愿,输入值后,将取值,程序将正常终止。
能否解释一下为什么会有这样的差异?
我刚刚发现 newEmptyMVar[A]
会产生 IO[MVar[A]]
,而 IO[A]
是懒惰的。
在第一种情况下,我得到两个不同的 MVar
。