Servlet中的线程安全和排队任务

时间:2012-04-23 17:55:03

标签: java jsp servlets

我几乎没有问题。据我所知,对容器的每个请求都变为HttpServletRequest。更多请求 - > HttpServletRequest的更多实例。然后,当请求对象调用名为'abc'的servlet时,会创建一个'abc'servlet的实例。让我们说同时3个请求来到'abc'servlet,然后是  (1)我想知道,这是否意味着每个请求创建了3个'abc'servlet实例?或者请求排队,直到向servlet发出一个请求。

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

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

我也读过this。那篇文章谈到了servlet。让我们说servlet的任务被移交给另一个类,然后我想知道如何使用单例模式?

3 个答案:

答案 0 :(得分:4)

容器可能会创建一个servlet实例池(下面的servlet规范摘录说明了详细信息)。它可以为三个并发请求使用三个不同的实例,或者可以对所有三个请求使用一个。因此,您的servlet必须是线程安全的,并且不应在其成员变量中具有状态。 SingleThreadModel标记接口将向容器发出信号,不要为多个并发请求使用相同的servlet实例(从而使您的servlet保持线程安全),但它不会阻止容器创建多个实例并使用它们同时。说得通?如果您的操作需要同步,那么您可以在Model类中处理它,而不是Controller。所以基本上在其他地方同步(或排队)就是答案。让servlet接受命令,然后运行它,而不会过多考虑过程。

<强>更新即可。您的案例的显式操作同步的一个非常基本的示例(不是我喜欢它,只是为了说明这一点)将是一个单件服务处理您的操作,其主do()方法声明为synchronized 。但是,理想情况下,您可以将数据库并发性委托给数据库和持久层(事务,乐观并发)。

根据{{​​3}}:

更正

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实例。

答案 1 :(得分:1)

1) No, only instance of servlet exists per server
2) No, each request is separate thread

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

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

请参阅此SO Wiki link以获取完整的讨论。

答案 2 :(得分:0)

同步特定任务,让我建议两种方式。

  1. 使用java synchronized块。您应该考虑哪个对象适合锁定对象。
  2. 使用数据库锁。例如select * from xxx for update