【问题标题】:Why do my blocking Futures not run on single core?为什么我的阻塞期货不能在单核上运行?
【发布时间】:2020-11-16 20:17:54
【问题描述】:

当我在只有 1 个内核的低功耗服务器上运行以下(简化的)代码时:

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")
}

日志中只显示“main”。如果我增加服务器以拥有更多内核,那么它​​就可以工作。我究竟做错了什么?即使内核有限,如何让 Scala/Java 运行每个线程?

我的理解是运行时应该使用一些逻辑来执行一个线程一段时间,然后切换到另一个线程。

scalaVersion := "2.12.12"

玩了一会儿后,我发现如果我将ExecutionContext.fromExecutor(Executors.newFixedThreadPool(30)) 用于我的 EC,它就可以工作。所以关于我理解全球 EC 和阻塞的方式一定是错误的。

【问题讨论】:

    标签: multithreading scala future


    【解决方案1】:

    我无法复制此问题。即使在单核上,使用ExecutionContext.global 时也应该至少有一个线程可用,因为默认计算是

    numThreads = Runtime.getRuntime.availableProcessors * 1 
    

    等等

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

    应该在那个线程同时执行

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

    应该在主线程中执行。

    请注意,即使只有一个可用线程,如果您一直使用blocking {},那么新线程仍会生成到maxExtraThreads

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

    因此问题可能出在其他地方。

    【讨论】:

      猜你喜欢
      • 2015-11-08
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 2012-10-19
      • 1970-01-01
      • 1970-01-01
      • 2011-12-12
      相关资源
      最近更新 更多