介绍
Web 服务端点使用的实例数取决于您使用的框架。
如果您使用简单的端点(即带有 Apache CXF 或 Spring webservices 的 JAX-WS),您将拥有一个用于所有线程/请求的服务实例(如您所说,Servlets)。因此,根据定义,这种服务是无状态的。但是如果你需要为服务添加一些状态,你可以这样做,但要由开发人员来确保服务线程安全。
当您使用 EJB 时,您拥有更大的灵活性:如果您使用无状态 bean,您将拥有一个实例池来管理所有请求(如果您的 poolSize=1,您将获得与 Apache CXF 相同的行为)。同样,您可以向无状态 bean 添加一些状态,但使其线程安全更加困难,因为您需要管理一个实例池。但是如果你需要一个状态,你可以使用一个有状态的 bean 来拥有一个框架,让你在线程安全方面的工作更轻松。
关于服务状态的一些提示
如果您不在服务中保留状态,则您的 Web 服务是线程安全的。换句话说,如果定义为线程安全,则无状态服务。
如果您需要一些应该由所有线程/请求共享的状态,您可以向无状态服务(JAX-WS 或具有 poolSize=1 的无状态会话 bean)添加一些状态,但您需要使其线程安全,添加 sycn 块(请不要同步您的@WebMethod
)。重要提示:理论上(和实践中),您永远不应该向无状态会话 bean 添加状态,因为池可以在“想要”时销毁/创建实例。
如果您需要保留仅由当前线程/请求使用的状态,您可以使用ThreadLocal
变量将一些状态添加到无状态服务,或者更轻松地使用有状态会话 bean。
现在终于回答你的问题了
- 当且仅当您使它们成为线程安全时,无状态会话 bean 才是线程安全的:它们不应该有状态 :-)
- 经典 Web 服务和无状态会话 bean Web 服务之间的唯一区别是第一个将具有单个实例,而第二个将使用实例池。如果您的 poolSize=1 您会得到相同的效果,但理论上,池可以在“想要”时破坏您的实例。
希望有帮助,