无状态对象始终是线程安全的?

bco*_*rso 4 java concurrency multithreading

Java Concurrency In Practice,第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?
    }
}
Run Code Online (Sandbox Code Playgroud)

题:

如上面的代码所示,如​​果多个线程尝试修改同一个ServletResponse变量会发生什么.

从我对内存分配的理解来看,上面的类似乎并不完全是线程安全的.

而到了参考ServletRequestServletResponse放在本地堆栈调用线程上,实际的对象存储上,可呈现在所有线程之间共享堆.

Tag*_*eev 6

这里的无状态对象是StatelessFactorization类.它是无状态的,因为它没有自己的状态,即它没有实例字段.因此,该对象是线程安全的.这resp是实现ServletResponse接口的另一个对象,它可能是也可能不是线程安全的.这里resp没有讨论线程安全性.


Gui*_*ira 6

当您发出将由servlet处理的HTTP请求时,service将调用其方法.如果您有多个客户端同时发出多个请求,则每个请求可能由不同的线程处理.但是,每个线程将接收的实例ServletRequest不同,因此您不会有多个线程修改这些对象的相同实例.每个线程都修改它们自己的实例.当然,魔术不会发生这种情况,您的servlet容器(例如Tomcat)是在这种特定情况下处理线程创建和为您分配这些实例的容器.ServletResponse

这是一个令人困惑的例子,因为你无法假设你总能在该方法中修改你想要的任何东西,一切都将神奇地保证线程安全.但是,这是一个通常由实际应用程序中的多个线程执行的方法的有趣示例.