为什么要使用新线程而不是未来{...} [英] Why new thread instead of future {...}
问题描述
此答案指导如何将java.util.concurrent.Future
转换为scala.concurrent.Future
,同时管理阻塞发生的位置:
This answer instructs how to convert java.util.concurrent.Future
into scala.concurrent.Future
, while managing where the blocking will occur:
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
我的任务与评论中的问题相同:
My queston is the same as a question asked in the comments:
future { jfuture.get }
怎么了?为什么您将多余的线程与Promise结合使用?
what's wrong with
future { jfuture.get }
? Why you used an extra thread combined with Promise?
回答如下:
它将阻塞您线程中的线程.如果您为此类期货配置了ExecutionContext,就可以了,但是默认的ExecutionContext包含的线程数与处理器的数量一样.
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.
我不确定我是否理解解释.重申一下:
I'm not sure I understand the explanation. To reiterate:
future { jfuture.get }
怎么了?在将来的内部进行阻塞与手动创建新线程并在其中进行阻塞不一样吗?如果没有,那有什么不同?
What's wrong with future { jfuture.get }
? Isn't blocking inside a future the same as manually creating a new Thread and blocking there? If not, how is it different?
推荐答案
future { jfuture.get }
和future { future { jfuture.get }}
之间几乎没有区别.
There is almost no difference between future { jfuture.get }
and future { future { jfuture.get }}
.
默认线程池中的运行区数量与您拥有的处理器数量一样.
There are as many treads in default thread pool as many you have processors.
使用jfuture.get
,您将获得1个线程被阻止.
With jfuture.get
you'll get 1 thread blocked.
假设您有8个处理器.还要假设每个jfuture.get
花费10秒.现在创建8个future { jfuture.get }
.
Let's assume you have 8 processors. Also let's suppose each jfuture.get
takes 10 seconds. Now create 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
评估来说太长了.
10 seconds is a little too long for 2+2
evaluation.
同一执行上下文中的所有其他future
和所有参与者将停止10秒.
All other future
s and all actors on the same execution context will be stopped for 10 seconds.
具有其他执行上下文:
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
,但是其他执行上下文允许您限制线程数.
You could implement blockingFuture
using new Thread(new Runnable {...
, but additional execution context allows you to limit threads count.
这篇关于为什么要使用新线程而不是未来{...}的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!