Java 处理游戏2.1中的阻塞操作

Java 处理游戏2.1中的阻塞操作,java,asynchronous,playframework,akka,actor,Java,Asynchronous,Playframework,Akka,Actor,我正在尝试创建一种在游戏中以特定方式处理阻塞操作的方法。首先,我描述了我的目标是什么,然后是我迄今为止所做的工作。你能告诉我我是否在正确的轨道上吗?如果是,你能帮助我理解如何完成代码吗?如果这不是正确的方法,你能建议一个更好的替代方案吗? 非常感谢你的帮助 目标: 希望将所有阻塞操作发送到一个线程,再发送到一个单独的线程,以便异步处理。传入的新请求不会占用更多线程,而是将它们放在一个队列(或任何类似的队列)中,由单个线程处理。对于额外线程异步处理的每个项目,必须收集一些文本并返回到浏览器 因此,

我正在尝试创建一种在游戏中以特定方式处理阻塞操作的方法。首先,我描述了我的目标是什么,然后是我迄今为止所做的工作。你能告诉我我是否在正确的轨道上吗?如果是,你能帮助我理解如何完成代码吗?如果这不是正确的方法,你能建议一个更好的替代方案吗? 非常感谢你的帮助

目标: 希望将所有阻塞操作发送到一个线程,再发送到一个单独的线程,以便异步处理。传入的新请求不会占用更多线程,而是将它们放在一个队列(或任何类似的队列)中,由单个线程处理。对于额外线程异步处理的每个项目,必须收集一些文本并返回到浏览器

因此,在阅读了文档和其他问题之后,似乎必须使用演员。我喜欢演员的概念,但以前从未使用过,所以我还在学习。这就是我所拥有的:

    package models;

    import java.io.*;
    import play.mvc.*;
    import play.libs.*;
    import play.libs.F.*;
    import akka.actor.*;

    public class ActorTest extends UntypedActor {
        static BufferedReader reader = new BufferedReader(new InputStreamReader(
                System.in));

        @Override
        public void onReceive(Object message) throws Exception {
            if (message instanceof String) {
                getSender().tell(
                        "You sent me " + ((String) message)
                                + " and the consol replied with "
                                + reader.readLine(), getSelf());
            } else
                unhandled(message);
        }

    }
正如您所看到的,阻塞操作是readLine()-只是一种测试方法

应该这样做吗?如果是这样,我假设从控制器开始,我知道如何使用承诺创建异步结果或其他东西。[…]

两个问题,我如何向演员发送消息并得到回复?我的意思是我能从电话()中得到结果吗? 我如何确保更多的线程不会被占用,所有的操作都进入一个队列?或者这已经由参与者处理了

你能提供一个控制器动作的例子吗

非常感谢你的帮助

PS仅供参考,我对这一切都很陌生,所以为了进入这一阶段,我发现这些文档非常有用——Akka演员页面、play当然还有一些关于演员的wiki页面

[编辑]
抱歉,我说的是单线程,但它可以是线程池-只要只使用分配的线程/线程池来处理阻塞io,而不是其他线程池。

您可以使用ask(而不是tell)向Akka参与者发送消息。它将返回给你一个未来,然后你可以映射到一个
承诺

然而,如果你不需要的话,你并不真的需要使用Akka。您可以简单地使用Futures/Promissions在后台运行阻塞操作

无论采用哪种方法,最终都会有一个将来,在将来完成时,您可以从中完成请求

在Play 2.2.x中使用Promise的示例 在Play 2.1.x中使用Promise的示例
你能包含一个代码示例吗?我一直试图在vane中编译一些东西,但似乎没有任何东西运行良好。-任何一个例子-使用提供的参与者或执行者都将不胜感激。好的,添加了一个基于文档的例子。我在当地试过,效果不错。您面临的编译问题是什么?嘿,是的,所以我的也可以编译,但这与我尝试的情况不同:我在获取承诺对象时遇到了一个问题,因为很明显,承诺promiseOfInt=Patterns。ask(actorTest,“hello”,6000)将不起作用,executor.submit(new Callable(…); 这两个都返回特性对象,但我在将它们转换为promisesOk时遇到了问题,我更新了如何实现这一点的答案。基本上,你需要在游戏2.1中使用
Akka.asPromise
,或者在游戏2.2中使用
Promise.wrap
,将Akka的
未来
转换为游戏的
Promise
。嘿,听着,非常感谢你的示例。出于兴趣,我的测试与actor.ask()asPromise()方法配合得很好。如果我使用遗嘱执行人的未来,会发生什么?是否有其他方法将其转换为承诺?我的编译器似乎不喜欢将asPromise()与executor.submit结合起来-
...
import play.libs.F.*;

public static Promise<Result> index() {
  Promise<Integer> promiseOfInt = Promise.promise(
      new Function0<Integer>() {
        public Integer apply() {
          // long-running operation (will run in separate thread)
          return 42;
        }
      });

  return promiseOfInt.map(
      new Function<Integer, Result>() {
        public Result apply(Integer i) {
          // 'i' is the result after Promise is complete
          return ok("Got result: " + i);
        }
      });
}
public static Promise<Result> index() {
    ActorRef myActor = Akka.system().actorFor("user/my-actor");

    return Promise.wrap(ask(myActor, "hello", 1000)).map(
        new Function<Object, Result>() {
            public Result apply(Object response) {
                return ok(response.toString());
            }
        });
}
...
import play.libs.F.*;

public static Result index() {
  Promise<Integer> promiseOfInt = play.libs.Akka.future(
      new Callable<Integer>() {
        public Integer call() {
          // long-running operation (will run in separate thread)
          return 42;
        }
      });
  return async(
      promiseOfInt.map(
        new Function<Integer,Result>() {
          public Result apply(Integer i) {
            // 'i' is the result after Promise is complete
            return ok("Got result: " + i);
          }
        }));
}
public static Result index() {
  ActorRef myActor = Akka.system().actorFor("user/my-actor");

  return async(
    Akka.asPromise(ask(myActor,"hello", 1000)).map(
      new Function<Object,Result>() {
        public Result apply(Object response) {
          return ok(response.toString());
        }
      }
    )
  );
}