一个线程能同时处理多个请求吗?

5
这个问题是关于Tomcat的,但适用于其他应用服务器/Servlet容器的答案也很有趣。
据我所知,每个请求都保证由一个线程从请求处理线程池中处理(让我们忽略应用程序请求处理代码异步执行的情况)。
但我想知道的是,是否保证单个线程在同一时间只能服务于一个请求?
换句话说,请求R1的工作是否可能被抢占,然后线程T1被用来处理请求R2,之后再继续处理R1(在T1上)?
可能,这个问题可以更加普遍化: 在同一个线程T1上,可否在执行Runnable R1时被另一个Runnable R2“抢占”?
我无法摆脱这种感觉,我可能只是忽略了Java多线程的一些基本原则,请给我指点!

1
不行,它做不到。一个线程会一直处理一个请求,直到完成。正在工作的线程永远不能被暂停然后给予另一个任务。 - f1sh
3个回答

6
不,多线程背后的原理是处理器可以同时运行多个线程,并在给定的时间量子之间切换它们。
但这只是处理器的工作。线程不再在工作单元之间切换,因为这已经是处理器的工作了。
当然,在异步servlet中,这并不完全正确。想法是执行长时间等待操作(向第三方服务器发出请求等)的请求可以在等待答案时释放服务线程,以便处理新的客户端请求。但是,这不是“常规”的线程操作,而是由应用程序服务器处理的。

感谢您的回答。我的原始帖子/标题有两个问题,答案相反(现在已经修正)。我假设您对问题“在同一线程T1上执行Runnable R1的执行是否可以被另一个Runnable R2的执行所抢占?”的回答是“否”,对吗? - Ward
@Ward 没错。如果不是这样,Runnable 将会与其 Thread 分离,这将导致许多奇怪的问题,例如 ThreadLocal - Kayaman
好的,我明白Runnable将会与它的线程一起运行。但我的问题略有不同:只要R1没有完成,线程T1是否对其他可运行项R2、R3不可用?换句话说,一个线程是否绑定到单个可运行项,直到该可运行项完成? - Ward
不,你的问题并不特别。线程或可运行对象没有任何奇怪的问题。它们按照你的期望执行,除非你刻意创建一些切换线程的可运行对象(毕竟你可以继承Thread类)。 - Kayaman

0
简而言之,答案是否定的。
详细来说:当你说线程运行一个“可运行”时,我想你是指处理器(CPU)运行一个线程。在Java中,线程代表正在进行的工作,而处理器则是实际的执行者。多线程执行可以发生在单核CPU上,其中处理器快速地在多个线程之间切换(每个线程都有其已定义的工作),以产生同时执行的错觉,但实际上是一个接一个地执行。
对于多核系统也是一样的,如果要运行的线程数量多于核心数,则它们将再次分配给各核心,并且每个核心按顺序执行线程,停止并切换到其他线程。

0

我同意,简短的回答是否定的。

当然:谈到任何值得拥有这个名字的"应用服务器"时,那么该服务器将使用一个线程池,所有的"工作包"都在其中。

因此,虽然R1在T1上不会被打断,但肯定会完成;之后T1肯定会运行一些T2;依此类推。


感谢您的回答。确实,我肯定会看到T1以后会被重复使用来处理一些R2、R3等等...但我的主要关注点是,在R1完成之前是否可能已经重新使用了T1...根据您的回答,这并不是情况... - Ward

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接