在Java中播放框架异步处理和阻塞I / O

前端之家收集整理的这篇文章主要介绍了在Java中播放框架异步处理和阻塞I / O前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的应用程序使用Play框架来处理REST请求.我需要在http请求处理程序中执行一些可能持久的阻塞I / O操作.并行地,我想要有效地处理一些短暂的持久性请求.

如下所述:

http://www.playframework.com/documentation/2.2.0/JavaAsync

持久的操作可以异步运行.另一方面,如下所述:

http://www.playframework.com/documentation/2.2.x/ThreadPools

Play框架使用相同的默认线程池,其中执行所有应用程序代码.至少在Java api中,不可能在不同的线程池上运行异步工作.

所以,我的问题是,如果值得运行潜在的阻塞I / O操作异步,考虑到这样一个操作使用相同的线程池的事实.或者也许最好增加默认线程池大小,在这种情况下不要打扰async api? (这样至少代码可读性会高得多)

@H_301_14@

解决方法

我建议您设置自己的上下文,并使用Plays F.Promise& A>运行您的阻止/ cpu密集型操作.与线程一样,最优解决方案取决于许多内核等等.

首先在applications.conf中设置你的上下文:

play {
  akka {
    akka.loggers = ["akka.event.Logging$DefaultLogger","akka.event.slf4j.Slf4jLogger"]
    loglevel = WARNING
    actor {
      default-dispatcher = {
        fork-join-executor {
          parallelism-min = 1
          parallelism-factor = 2
          parallelism-max = 6
        }
      }
      my-context {
        fork-join-executor {
          parallelism-min = 1
          parallelism-factor = 4
          parallelism-max = 16
        }
      }
    }
  }
}

然后在控制器中,使用Plays Promises(我使用Java 8)使用你的上下文:

public static F.Promise<Result> love() {
    ExecutionContext myExecutionContext = Akka.system().dispatchers().lookup("play.akka.actor.my-context");

    F.Promise<Integer> integerPromise = F.Promise.promise(() ->
            LongRunningProcess.run(10000L),myExecutionContext);

    F.Promise<Integer> integerPromise2 = F.Promise.promise(() ->
            LongRunningProcess.run(10000L),myExecutionContext);

    return integerPromise.flatMap(i -> integerPromise2.map(x -> ok()));
}

这样,您的Play应用程序仍将处理默认调度程序执行上下文中的短暂持久请求,并且阻止/ cpu密集型将在我的上下文中运行.

我为您演示了一个很简单的例子,请查看github.

@H_301_14@ @H_301_14@

猜你在找的Java相关文章