Comment by tsimionescu

Comment by tsimionescu 9 days ago

1 reply

> Edit 2: I can definitely replicate the same bug in Scala, so it is not like Go is unique for the example in that blog post.

Could you share some details on the program and the execution environment? Per my understanding of the Java memory model, a JVM should not experience this problem. Reads and writes to references (and to all 32 bit values) are explicitly guaranteed to be atomic, even if they are not declared volatile.

kokada 7 days ago

    import java.util.concurrent.Executors
    import scala.concurrent.{ExecutionContext, ExecutionContextExecutor, Future}

    trait IceCreamMaker {
      def hello(): Unit
    }

    class Ben(name: String) extends IceCreamMaker {
      override def hello(): Unit = {
        println(s"Ben says, 'Hello my name is $name'")
      }
    }
    class Jerry(name: String) extends IceCreamMaker {
      override def hello(): Unit = {
        println(s"Jerry says, 'Hello my name is $name'")
      }
    }

    object Main {
      implicit val context: ExecutionContextExecutor = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(2))

      def main(args: Array[String]): Unit = {
        val ben = new Ben("Ben")
        val jerry = new Ben("jerry")
        var maker: IceCreamMaker = ben
        def loop0: Future[Future[Future[Future[Any]]]] = {
          maker = ben
          Future { loop1 }
        }
        def loop1: Future[Future[Future[Any]]] = {
          maker = jerry
          Future { loop0 }
        }
        Future { loop0 }
        while (true) {
          maker.hello()
        }
      }
  }

Here. I am not saying that JVM shouldn't have a stronger memory model, after thinking for a while I think the issue is the program itself. But feel free to try to understand.