2

我有几个问题。据我所知,对容器的每个请求都会变成HttpServletRequest. 更多请求-> 更多实例HttpServletRequest。然后,当请求对象调用名为“abc”的 servlet 时,会创建一个“abc”servlet 实例。假设同时有 3 个请求来到 'abc' servlet,那么
(1)我想知道,这是否意味着每个请求都会创建 3 个 'abc' servlet 实例?或者请求排队,直到对 servlet 的一个请求完成。

然后让我们说,3 请求“abc”servlet 执行一些数据库进程,这些进程可能同时是插入和检索。那么
(2)一个请求是否应该在队列中,直到其他请求的servelt完成任务(同步)或所有servlet作为多线程作为单独的任务(非同步)完成他们的数据库任务?
(3)。如果它们以不同步的方式工作,我们如何使这些任务同步(比如说,只有一个特定的任务——将一些东西保存到数据库)并排队?为此,最好是实现 servletSingleThreadModel还是使用根据单例模式创建的类中的方法?那么它对容器的性能有何影响呢?

简而言之,我们如何为所有请求同步运行特定任务?

我也读过这个。那篇文章谈到了 servlet。假设一个 servlet 的任务被移交给另一个类,那么我想知道在这个上使用单例模式怎么样?

4

3 回答 3

4

一个容器可以创建一个 servlet 实例池(下面的 servlet 规范摘录解释了详细信息)。它可以对三个并发请求使用三个不同的实例,也可以对所有三个请求使用一个。因此,您的 servlet 需要是线程安全的,并且不应在其成员变量中包含状态。这SingleThreadModel标记接口将向容器发出信号,不要将同一 servlet 实例用于多个并发请求(从而使您的 servlet 线程安全),但它不会阻止容器创建多个实例并同时使用它们。说得通?如果您的操作需要同步,那么您在模型类中处理它,而不是在控制器中。所以基本上在别处同步(或排队)就是答案。让 servlet 接受命令并直接运行它,而无需在过程中花太多心思。

更新。对于您的情况,一个非常基本的显式操作同步示例(不是我喜欢它,只是为了说明这一点)是让一个单例服务处理您的操作,并将其 maindo()方法声明为synchronized. 不过,理想情况下,您会将数据库并发委托给您的数据库和持久层(事务、乐观并发)。

根据servlets 规范更正

In the default case of a servlet not implementing SingleThreadModel and not hosted in a
distributed environment, the servlet container must use only one instance of a servlet class
per servlet definition.
In the case of a servlet that implements the SingleThreadModel interface, the servlet
container may instantiate multiple instances of that servlet so that it can handle a heavy
request load while still serializing requests to a single instance.

话虽如此,除非您使用该单线程模型标记,否则您将只有一个 servlet 实例。

于 2012-04-23T18:01:21.483 回答
1
1) No, only instance of servlet exists per server
2) No, each request is separate thread

您的服务器不应包含任何实例变量(或)静态变量,那么同步不会有任何问题,因为每个线程都有自己的局部变量副本和执行序列。

3)你可以通过在doGet()前面加上同步前缀来使servlet同步,doPost()方法是在同步块的帮助下进行的。但这是不好的做法。

请参阅此SO Wiki 链接以进行完整讨论。

于 2012-04-23T18:02:22.273 回答
0

要同步特定任务,让我建议 2 种方法。

  1. 使用 javasynchronized块。您应该考虑什么对象适合锁定对象。
  2. 使用数据库锁。如select * from xxx for update
于 2012-04-23T18:07:18.863 回答