gpt4 book ai didi

multithreading - Scala Future vs Thread 用于长时间运行的任务而没有结果

转载 作者:行者123 更新时间:2023-12-04 04:30:02 25 4
gpt4 key购买 nike

我想在 Scala 2.11 中构建一个简单的服务器来监听套接字。它应该从套接字异步读取数据并将数据从 RxScala 传递到 Observable 中。

我有一个 Java ServerSocket应使用方法从中读取数据 readData这是阻塞。此方法启动一次 并运行直到整个程序停止:

val server = new ServerSocket(port)
def readData(server: ServerSocket): Unit = ???

当从套接字读取数据时,我发现了两种不同的方法来避免阻塞整个程序:
new Thread {
override def run(): Unit = {
readData(server)
}
}.start()


Future {
blocking {
readData(server)
}
}

因为 Future 中没有包装返回值,然后可以将其传递给其他任务,所以 Future 的唯一任务是使计算非阻塞。所以我想知道这些方法之间是否有更大的差异?查看 Future 的实现,它看起来还使用给定的块创建并运行 Runnable。那么,如果一个人有一个永远/长时间运行的任务而没有结果,那么这些方法之一是否更可取?

最佳答案

So is one of these approaches preferable if one has a long or forever running task without a result?



这两个示例的不同之处在于前者为每个请求分配一个新线程,而第二个示例隐式使用 Scala 的默认 ExecutionContext ,它由 ForkJoinPool 支持,它基本上是一个可以根据需要向上/向下扩展的线程池。

需要记住,线程不是免费的,它需要分配一个堆栈(根据操作系统而异),需要进行系统调用来注册该线程等(您可以在 Why is creating a Thread said to be expensive? 中阅读更多内容) .

通常,我会采用后者的“天真”方法,即使用 Futureblocking ,后者使用全局 ExecutionContext 。最重要的是, 我会对我的代码 进行基准测试,以确保我对代码的行为方式感到满意,然后根据这些发现进行调整。

另一个需要注意的重要事项:使用线程或线程池来处理事件仍然不会异步,您只是使用多个线程来处理阻塞同步 IO。我不熟悉 SocketServer API,但一般来说,如果它公开一个自然的异步 API,则根本不需要额外的线程。例如,看看 Netty,它内置了对异步 IO 的支持。

编辑

正如您所阐明的那样,该操作是对 readData 的单次调用,并且只要应用程序处于事件状态,该操作就会一直运行,因此在这里使用单个专用 Thread 会是一个更好的主意。

关于multithreading - Scala Future vs Thread 用于长时间运行的任务而没有结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38617603/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com