【问题标题】:Scala Future vs Thread for a long running task without resultScala Future vs Thread 用于长时间运行的任务而没有结果
【发布时间】:2016-12-01 17:43:03
【问题描述】:

我想在 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。那么,如果一个人有一个单一且永远/长时间运行的任务而没有结果,那么这些方法中的一种更可取吗?

【问题讨论】:

    标签: multithreading scala asynchronous concurrency future


    【解决方案1】:

    如果一个人有很长或永远 运行任务没有结果?

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

    需要记住,线程不是免费的,它需要分配一个堆栈(取决于操作系统),需要进行系统调用以注册该线程等(您可以阅读更多在Why is creating a Thread said to be expensive?)。

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

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


    编辑

    正如您已经阐明的那样,该操作是对readData单个 调用,并且只要应用程序处于活动状态,该操作就会运行,单个专用Thread 会更好想法在这里。

    【讨论】:

    • 我可能是错的,但我只启动一个线程/未来,因此应该不需要池。所以这个 Socket 上只有一个连接。
    • @nico 如果readData 不是重复性操作,那么您也可以。如果操作运行时间较长,则最好使用专用线程
    • 好的,这正是我想知道的,似乎我的问题不够精确。我有一个长时间运行的操作,我把它放在一个线程或未来。
    • @nico 众所周知,线程池内的操作不应该长时间运行。你问什么是长期运行?好吧,实际上并没有就此达成协议。一般来说,让我们说一些需要超过 200-400 毫秒才能完成的事情。如果是这样,请使用专用线程。
    • 由于我的操作只要程序运行就运行,所以专门的线程应该是最好的解决方案和我的问题的答案,谢谢!
    【解决方案2】:

    异步 ​​I/O 相对于同步的主要(如果不是单一的)优势是少量线程可以支持大量连接。由于程序中的连接数很少(1),我建议使用专用线程。这使程序更简单、可维护、更高效。

    【讨论】:

    • OP 声明他有一个读取数据的阻塞操作。这与异步 IO 有什么关系?
    • 未来是异步 I/O 的标志。
    • 我不确定我是否同意。 Future 实际上可以隐藏任何东西,真的不能保证真正的异步操作。
    猜你喜欢
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多