java - 为什么新线程而不是 future {...}

标签 java multithreading scala blocking future

This answer指示如何将 java.util.concurrent.Future 转换为 scala.concurrent.Future,同时管理阻塞发生的位置:

import java.util.concurrent.{Future => JFuture}
import scala.concurrent.{Future => SFuture}

val jfuture: JFuture[T] = ???
val promise = Promise[T]()
new Thread(
  new Runnable {
    def run() { promise.complete(Try{ jfuture.get }) }
  }
).start
val future = promise.future

我的问题与评论中的问题相同:

what's wrong with future { jfuture.get }? Why you used an extra thread combined with Promise?

回答如下:

it'll block thread in your thread pull. If you have a configured ExecutionContext for such futures it's fine, but default ExecutionContext contains as many threads as you have processors.

我不确定我是否理解了解释。重申一下:

future { jfuture.get } 有什么问题?在 future 中阻塞与手动创建新线程并在那里阻塞不一样吗?如果不是,那有什么不同?

最佳答案

future { jfuture.get }future { future { jfuture.get }} 几乎没有区别。

默认线程池中的线程数与处理器的数量一样多。

使用 jfuture.get,您将阻塞 1 个线程。

假设您有 8 个处理器。我们还假设每个 jfuture.get 需要 10 秒。现在创建 8 个 future { jfuture.get }

val format = new java.text.SimpleDateFormat("HH:mm:ss").format(_: Date)

val startTime = new Date
(1 to 8) map {_ => future{ Thread.sleep(10000) }}
future{
  2+2
  println(s"2+2 done. Start time: ${format(startTime)}, end time: ${format(new Date)}")
}

// 2+2 done. Start time: 20:48:18, end time: 20:48:28

10 秒对于 2+2 评估来说有点太长了。

所有其他 future 和同一执行上下文中的所有 actor 将停止 10 秒。

具有额外的执行上下文:

object BlockingExecution {
  val executor = ExecutionContext.fromExecutor(new ForkJoinPool(20))
}

def blockingFuture[T](f: => T) = {
  future( f )(BlockingExecution.executor)
}

val startTime = new Date
(1 to 8) map {_ => blockingFuture{ Thread.sleep(10000) }}
future{
  2+2
  println(s"2+2 done. Start time: ${format(startTime)}, end time: ${format(new Date)}")
}

// 2+2 done. Start time: 21:26:18, end time: 21:26:18

您可以使用 new Thread(new Runnable {... 实现 blockingFuture,但额外的执行上下文允许您限制线程数。

关于java - 为什么新线程而不是 future {...},我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21190140/

相关文章:

java - 使用 Java 中的 DocumentBuilder/Document 在 XML 文件中查找 "untagged"内容

java - 终止 mvn spring-boot :run doesn't stop tomcat

java - 多个线程读取变量

scala - SBT 在多项目构建中添加项目 ID 以登录

java - 使用 Gson 和改造的 Java 的 Json 错误 [预期为 BEGIN_ARRAY,但在第 1 行第 70 列路径 $.Data 处为 BEGIN_OBJECT]

java - 在 Java 中使用线程和递归计算斐波那契数列

.net - 图形 GDI+ 上的多线程

arrays - Scala - 将 Array[String] 转换为 Array[Double]

scala - 通过反射获取案例类的参数

java - 如何在 Windows 路径系统中添加 Java bin 文件夹路径