首页 文章

异步阻塞线程魔术

提问于
浏览
3

我一直在学习游戏,而且我已经掌握了大部分主要概念,但我正在努力应对平台正在做的所有这些事情 .

特别是,假设我有一个控制器,它会做一些耗费时间的事情 . 现在我明白了如何使这些东西看起来不会阻塞,但如果它是资源密集型的东西,当然最终它必须阻止 somewhere . 根据文件:

通过将同步IO包装在Future中,您无法神奇地将同步IO转变为异步 . 如果您无法更改应用程序的体系结构以避免阻塞操作,那么在某些时候必须执行操作,并且该线程将阻塞 . 因此,除了将操作封装在Future中之外,还需要将其配置为在单独的执行上下文中运行,该上下文已配置有足够的线程来处理预期的并发性 .

通过 Future 做的这一点可能是在一个单独的线程池中处理的,Scala / Play在框架中如何/有什么魔力来协调这些线程,这样哪个线程正在监听HTTP套接字块足够长的时间来做所有复杂的处理(数据库加载,序列化到JSON等等) - 在单独的线程中,然而以某种方式返回原始阻塞线程,必须将某些东西发送回客户端以获取该请求?

1 回答

  • 2

    免责声明:这是一般问题的简化答案,我不想通过进入Play和Akka内部使这更加复杂 .

    一种方法是让一个线程监听套接字,但不写入它,让我们称之为 A . A 跨越 Future ,其本身包含计算所需的所有数据 . 重要的是不要将执行处理的线程与正在处理的数据混淆,因为数据(内存)由所有线程共享(有时需要显式同步) . 未来将由一个线程 B 处理(最终) .

    现在,我需要 A 阻止直到 B 完成?它可以(并且在许多一般情况下可能是正确的解决方案),但在这种情况下,我们几乎不想停止收听我们的套接字 . 所以不,我们不会,忘记消息的一切,继续它的生命 .

    因此,当完成 B 时,可能会映射Future或者有一个发送正确响应的侦听器 . B 本身可以根据原始邮件中的信息发送它!您只需要小心同步对套接字的访问,以避免与可能已经并行处理前一个或后一个消息的可能线程冲突 C .

    通过让线程产生更多线程,一些线程写入数据和其他读取数据的队列等等,事情显然会变得更加复杂 . (Play,基于Akka,当然包括很多消息队列) . 但我希望能说服你,虽然这句话是正确的:

    通过将同步IO包装在Future中,您无法神奇地将同步IO转变为异步 . 如果您无法更改应用程序的体系结构以避免阻塞操作

    在许多(大多数?)情况下,应用程序架构的这种变化当然是可能的,当然也是在Play内部完成的 .

相关问题