1

When I run the following (simplified) code on a low powered server with only 1 core:

implicit val context: ExecutionContextExecutor = scala.concurrent.ExecutionContext.global

Future(blocking {
  while (true) {
    java.lang.Thread.sleep(1000)
    println("thread 1")
  }
})

while (true) {
  java.lang.Thread.sleep(1000)
  println("main")
}

Only "main" shows up in the logs. If I increase the server to have more cores, then it works. What am I doing wrong? How to make Scala/Java run every thread even when there are limited cores?

My understanding is that the runtime should use some logic to execute one thread for a bit, then switch to the other thread.

scalaVersion := "2.12.12"

After a bit of playing around, I found that if I use ExecutionContext.fromExecutor(Executors.newFixedThreadPool(30)) for my EC it works. So something about the way I understand the global EC & blocking must be wrong.

Mario Galic
  • 47,285
  • 6
  • 56
  • 98
samthebest
  • 30,803
  • 25
  • 102
  • 142

1 Answers1

1

I am not able to replicate this problem. Even on a single core there should be at least one thread available when using ExecutionContext.global because the default calculations is

numThreads = Runtime.getRuntime.availableProcessors * 1 

and so

Future(blocking {
  while (true) {
    java.lang.Thread.sleep(1000)
    println("thread 1")
  }
})

should execute in that thread whilst

while (true) {
  java.lang.Thread.sleep(1000)
  println("main")
}

should execute in the main thread.

Note even with just a single thread available, if you consistently used blocking {} then new threads would still be spawned up to maxExtraThreads

scala.concurrent.context.maxExtraThreads = defaults to "256"

Hence the problem likely lies somewhere else.

Mario Galic
  • 47,285
  • 6
  • 56
  • 98