在Java Concurrency In Practice, Section 2.1中,它声明:
无状态对象始终是线程安全的。
并以下面的课程为例:
@ThreadSafe
public class StatelessFactorization implements Servlet {
public void service(ServletRequest req, ServletResponse resp){
BigInteger i = extractFromRequest(req);
BigInteger[] factors = factor(i);
encodeIntoResponse(resp, factors); // <-- isn't it possible for resp to be
// modified by mult. threads at once?
}
}
如上面的代码所示,如果多个线程试图修改相同的ServletResponse
变量会发生什么。
从我对内存分配的理解来看,上面的类似乎并不完全是线程安全的。
虽然对ServletRequest
和ServletResponse
的引用放在调用线程的本地堆栈上,但实际的对象存储在堆上 - 它们在所有线程之间共享。
答案 0 :(得分:5)
此处无状态对象为StatelessFactorization
类。它是无状态的,因为它没有自己的状态,即它没有实例字段。因此,该对象是线程安全的。 resp
是实现ServletResponse
接口的另一个对象,它可能是也可能不是线程安全的。这里没有讨论resp
的线程安全性。
答案 1 :(得分:5)
当您发出将由servlet处理的HTTP请求时,将调用其a
方法。如果您有多个客户端同时发出多个请求,则每个请求可能由不同的线程处理。但是,每个线程将收到的service
和ServletRequest
的实例不同,因此您不会让多个线程修改这些对象的相同实例。每个线程都修改它们自己的实例。当然,魔术不会发生这种情况,您的servlet容器(例如Tomcat)是在这种特定情况下处理线程创建和为您分配这些实例的容器。
这是一个令人困惑的例子,因为你无法假设你总是可以在该方法中修改你想要的任何东西,并且一切都将神奇地保证线程安全。但是,它是一个通常由实际应用程序中的多个线程执行的方法的有趣示例。