1

Given this code:

object Test {

    import scala.concurrent.ExecutionContext.Implicits.global

    def main(args: Array[String]): Unit = {
        val f: Future[String] = Future { "Test" }
        f.onComplete {
            case Success(name) => println(name)
            case Failure(t) => t.printStackTrace()
        }
    }
}

I see no output, however changing println to System.out.println works:

object Test {

    import scala.concurrent.ExecutionContext.Implicits.global

    def main(args: Array[String]): Unit = {
        val f: Future[String] = Future { "Test" }
        f.onComplete {
            case Success(name) => System.out.println(name)
            case Failure(t) => t.printStackTrace()
        }
    }
}

Also using println with a standard Thread also works:

object Test {

    def main(args: Array[String]): Unit = {
        val t = new Thread() {
            override def run(): Unit = println("Test")
        }
        t.start()
        t.join()
    }
}

Why is this?

Chris Martin
  • 30,334
  • 10
  • 78
  • 137

4 Answers4

4

You have to wait for the Future's completion. So your System.out.println version also might output or not.

object Test {

    import scala.concurrent.ExecutionContext.Implicits.global

    def main(args: Array[String]): Unit = {
        val f: Future[String] = Future { "Test" }
        f.onComplete {
            case Success(name) => println(name)
            case Failure(t) => t.printStackTrace()
        }
        Await.result(f)
    }
}
yanana
  • 2,241
  • 2
  • 18
  • 28
  • That makes sense but I still don't understand why System.out.println works and println does not? I tested this 100 times and every time System.out.println works but println does not. As I understand it println is just an alias for System.out.println. I realise that threads are non deterministic but I don't believe my results are a simple coincidence –  Jul 31 '15 at 13:56
4

Future and onComplete execute in separated daemon threads. When your main thread terminates (after last instruction) daemon threads also terminate. In your case they have no time to execute code. Make your main code live long, for example, Thread.sleep(100).

Zernike
  • 1,758
  • 1
  • 16
  • 26
  • I understand that this is little late, but can you provide a reference to 'Future and onComplete execute in separated daemon threads' in the scala documentation? I am unable to locate the specification which states this. – ksceriath Apr 20 '20 at 02:42
0

Because your program has exited:

def main(args: Array[String]): Unit = {
    val f: Future[String] = Future { "Test" }
    f.onComplete {
      case Success(name) => println(name)
      case Failure(t) => t.printStackTrace()
    }
    Thread.sleep(100)
  }
chengpohi
  • 14,064
  • 1
  • 24
  • 42
0

So it seems that the answer lies in this answer. Scala's println is not an alias for System.out.println but Console.println which handles threads differently

Community
  • 1
  • 1