0

一般来说,围绕被动异步代码异步处理请求(play,akka,netty等)存在巨大的噱头。 以这种方式执行代码时,建议不要在任何地方阻止和使用异步库。 如果我正确理解这一点,这种方式,而不是为每个请求创建一个线程,我们最终有线程执行者为这些库带来的执行的多个部分(主要处理请求,异步调用服务执行程序,异步数据库驱动程序执行程序等)如何实现异步数据库库?

这种方式执行最终分裂成多个线程(=在多个执行者中)。 这些异步库如何实现以便带来任何好处?因为在异步数据库驱动程序具有执行程序的情况下,该程序运行一个简单地等待数据库答案的线程,所以我认为它不会带来任何好处。我们最终会等待任何东西,只需创建额外的线程来执行,等待不会有任何帮助。还是呢?

+1

这些库使用固定大小的线程池和异步IO。他们不会为每个请求打开一个新线程。 –

+0

而且你知道,这不是一个好问题。您列出了各种不同的框架;你在找什么?有人向你详细解释这些工作是如何在内部工作的? – GhostCat

回答

1

我认为关于异步库的常见误解是因为想象它们如何工作的最简单方法是考虑如何使用可用的工具编写库的语言来实现它们该语言 - 通常会导致思考“如果DoWorkAsync必须等待其他事情完成,那么DoWorkAsync肯定会占用线程,直到完成工作”。这听起来很浪费,而且唯一的好处是异步库处理管理将用于等待工作的线程。

但是,这些异步方法实际上可以与低级别通信形式一起使用,而不是在Java中直接访问。

当异步工作必须处理某种形式的IO时,它不能立即从中获取数据(包括各种各样的东西,比如IPC,磁盘访问和网络访问 - 等等,通过扩展,数据库调用),操作系统将与设备驱动程序进行通信,该驱动程序具有对异步调用的内置低级别支持,以便它可以开始工作,然后触发某种中断以告知操作系统何时完成工作。在此期间,不需要托管线程继续存在(并继续吸取资源) - 当设备驱动程序正在处理工作时,不需要等待它的线程。当设备驱动程序指示其异步工作已完成时,操作系统会传递此信息,并使用一个线程继续工作。

以上是一个非常简单的解释(并且可能在各种方式上都不准确),但希望它可以跨越 - 线程不需要等待异步数据,它可以解决您的原始问题。

有这个优秀的(和简洁)的文章中了解更多信息:There Is No Thread(这是关于.NET但同样的原则也适用)