关于servlet的线程安全

可能重复:
servlet如何工作? 实例化,会话变量和multithreading

servlet是线程安全的吗? 例如,如果我打开5个不同的浏览器并向容器中的一个servlet发送请求,它是否仍然是线程安全的,我特意指的是service()方法

您的问题归结为: 从同一对象上的多个线程调用方法是线程安全的 。 答案是: 这取决于 。 如果您的对象(让它成为servlet)是无状态的或只有final字段,这完全是线程安全的。 局部变量和参数是线程的本地变量(驻留在堆栈上,而不是堆上)。

此外,每个service()调用都会接收ServletRequestServletResponse不同实例。 但是这里是一个不安全的servlet的例子:

 public class UnsafeServlet implements Servlet { private int counter; public void init(ServletConfig config) throws ServletException { } public void service(ServletRequest request, ServletResponse response) ++counter; } public void destroy() { } } 

由于多个线程可以访问counter变量,因此必须以某种方式保护它:使用synchronizedvolatile不够):

 synchronized(this) { ++counter; } 

AtomicInteger

 private AtomicInteger counter = new AtomicInteger(); //... counter.incrementAndGet(); 

在这种特殊情况下, AtomicInteger要好得多,因为它使用CAS CPU操作是无锁的,而synchronized是互斥锁。