java中的servlet是线程安全的嘛_关于java:为什么Servlet中的实例变量不是线程安全的...

本问题已经有最佳答案,请猛点这里访问。

当我读取Head First Servlet and JSP时,他们说实例变量是非线程安全的。

我不太明白这个说法。例如:我有一个servlet,它的名称是ActionServlet.java。每次将每个用户的请求发送到服务器时,容器都将创建一个新线程并创建新的ActionServlet实例。

ActionServlet可具有以下结构:

public class ActionServlet extends HttpServlet {

// example of instance variable

Instance variable;

public void processRequest(HttpServletRequest request, HttpServletResponse response) {

// process something relating to instance variable

}

}

所以,因为所有这些线程都为ActionServlet创建了一个新的类实例,所以这里我看不到任何问题。因为这些线程的实例是相互独立的。

请找出在多线程环境中使用实例变量时出现的问题。

谢谢)

考虑从两个线程对同一对象调用相同的方法。

@Danielfischer我无法想象不同的线程如何使用相同的对象,因为:1)这些变量是私有的2)这个线程的对象总是不同于其他线程(我认为)。我上面有一个示例代码。请更清楚地告诉我。

@hqt:容器创建servlet的唯一实例,将其存储在一些全局数据结构中(例如map),每次请求进入时,它都从映射中获取适当的servlet(基于请求的路径),并调用其服务方法。servlet的字段是私有的这一事实没有任何影响。容器甚至不关心它们。

@哦,谢谢你的解释。您的评论对我来说仍然很好:我想问最后一个问题:那么,当没有线程使用servlet的实例时,该实例将从内存中删除并在需要时重新创建,对吗?

servlet未存储在线程池中。线程存储在线程池中。servlet是在部署时或第一次需要时创建的,然后保存在内存中,直到取消部署应用程序为止。如果它是从内存中删除的,那么当一个新的请求出现时,容器将不得不重新创建一个实例,因此会违反规范,而且无论如何也没有从内存中删除它的好理由,因为servlet通常是无状态的,因此根本不会消耗太多内存。

您知道在Spring中连线的服务/组件类是否是这样的吗?

你犯的错误是:

So, because all these threads create a new class instance for

ActionServlet, so I don't see any problem here. because instances of

these thread is separate of each other.

容器不会为每个请求创建servlet类的新实例。它重用现有的一个。这就是为什么它们不是线程安全的。

Stripes操作框架确实为每个请求创建了一个新的实例,所以在该框架下这是一个不错的假设。但是,例如,struts 1遵循servlet模型,并且不会为每个请求创建新的操作。

这并不意味着容器仅限于一个实例,理论上它可以创建多个实例,但它不是一个特定的行为,因此无法依赖。大多数流行的没有。

实际上,容器只能创建一个实例。规范说明如下:"对于不在分布式环境中承载的servlet(默认情况下),servlet容器在每个servlet声明中只能使用一个实例。"

哦。感谢@jbinzet和will hartung。这本书并没有向我展示容器只是为一个servlet创建一个实例。

because all these threads create a new class instance (action.java), so I don't see any problem

您假设每个线程都创建一个类实例,该实例只能由该线程使用,所以您没有任何问题。

但是,尝试想象一下,使用特定的示例,可以从两个线程访问同一个实例。如果同时使用您的request和response成员,会发生什么情况?也许您将从无法识别的请求中读取数据,并且您将编写一个混合了两部分的不一致响应。

因此,在您的情况下,实例变量也不是线程安全的,因为如果两个线程访问同一个实例,它们会相互干扰。

问题是,action.java并不总是实例化的,但它是从实例池中获取的,请求线程也是如此,它们是从线程池中获取的,因此servlet实例可以由多个请求共享。

servlet没有实例池。每个servlet声明只有一个servlet实例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值