使用`Future`运行一些永不完成的循环任务是否正确?

Fre*_*ind 0 scala future

在我们的项目中,我们需要执行一个侦听队列并在循环中处理即将发生的消息的任务,该循环永远不会完成.代码看起来像:

def processQueue = {
  while(true) {
    val message = queue.next();
    processMessage(message) match {
      case Success(_) => ...
      case _ => ...
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

所以我们想在一个单独的线程中运行它.

我可以想象两种方法,一种是用Thread我们在Java中做的:

new Thread(new Runnable() { processQueue() }).start();
Run Code Online (Sandbox Code Playgroud)

另一种方式是使用Future(我们现在这样做):

Future { processQueue }
Run Code Online (Sandbox Code Playgroud)

我只是想知道Future在这种情况下使用是否正确,因为我知道(这可能是错误的),Future意味着要运行一些任务,将在未来的某个时间完成或返回结果.但我们的任务永远不会完成.

我也想知道scala中最好的解决方案是什么.

Mic*_*jac 5

A Future应该是一个最终会存在的值,所以我认为创建一个永远不会实现的值是没有意义的.它们也是不可改变的,所以将信息传递给它们是禁忌.并且在Future黑暗的道路声音中使用一些外部引用的队列来下去.

你所描述的基本上是一个Akka Actor,它有自己的FIFO队列,有一个receive处理消息的方法.它看起来像这样:

import akka.actor._

class Processor extends Actor {
    def receive = {
        case msg: String => processMessage(msg) match {
            case Success(x) => ...
            case _ => ...
        }
        case otherMsg @ Message(_, _) => {
            // process this other type of message..
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您的应用程序可以Processor使用ActorSystem(或其他一些精心设计的这些actor组)创建此actor 的单个实例:

val akkaSystem = ActorSystem("myActorSystem")
val processor: ActorRef = akkaSystem.actorOf(Props[Processor], "Processor")
Run Code Online (Sandbox Code Playgroud)

并发送消息:

processor ! "Do some work!"
Run Code Online (Sandbox Code Playgroud)

简而言之,使用像Akka这样的并发框架比在单独的线程上创建自己的处理队列更好.该FutureAPI是最绝对不是要走的路.

我建议仔细阅读Akka文档以获取更多信息.