San*_*dal 7 java multithreading servlets ejb thread-safety
根据我的理解,servlet容器创建有限的servlet实例和每个servlet实例的多个线程,并重用这些线程和实例.
因为有多个线程实例,所以它们不是"线程安全的"(虽然我知道使用Thread-safety编写它们并不困难).
另一方面,EJB容器不创建EJB的线程,而是仅重用EJB对象(使用池).由于EJB实例没有多个线程,因此不存在线程安全问题.
我的问题:为什么有不同的行为?将EJB作为Servlet(线程不安全)工作不是一个好主意吗?
我确定我错过了一些东西,并希望了解那个缺失的部分.
可能是因为它们的设计并没有考虑到相同的目标.
servlet API是一个简单的API,非常接近HTTP协议,您可以在其上构建应用程序或框架.HTTP协议是完全无状态的,我想有必要构建一个无状态的API.在servlet API(例如Stripes)之上构建的几个框架在每个请求中使用一个Action实例,它不会同时使用.
EJB是一个更复杂和更高级别的框架,旨在尽可能简单地实现事务性业务逻辑.它更重量级,并且具有有状态的组件.这些显然需要是线程安全的.我想因为无状态bean也是自然的线程安全.
应该注意的是,例如,Spring bean默认是单例,因此必须遵循与servlet相同的规则.因此,多种设计可以提供或多或少相同的功能.
线程与性能优化无关.如果需要同时处理3个请求,则需要3个线程,无论请求是发送到servlet还是发送到EJB.
对你的问题最简单的回答当然是让一个EJB像Servlet一样工作是个好主意,在EJB 3.1中我们添加了一个可以做到这一点的组件: @Singleton
的@Singleton豆可以是多线程的像小服务程序,有两种方法:
@ConcurrencyManagement(BEAN)@ConcurrencyManagement(CONTAINER)以及@Lock(READ)在哪里并发所需的方法和@Lock(WRITE)上不是线程安全的方法.Servlet多年来从未有过的另一件事是<load-on-startup>,它允许Servlet急切加载并在应用程序启动时工作.
为了匹配Servlet,<load-on-start>我们添加了@Startup可以添加到任何@SingletonEJB 的注释,并使其在应用程序启动时启动.这些bean将@PostConstruct在应用程序启动时调用其方法,并@PreDestroy在应用程序关闭时调用它们.
您可以使用数字(<load-on-startup>1</load-on-startup>)来指示使用@Startupstart注释bean 的顺序,而不是使用注释Bean来@DependsOn指定bean,并指定需要在注释bean之前启动的bean列表.
我们在EJB 3.1中为了对齐Servlet和EJB而做的一个鲜为人知且理解的方面当然是允许将EJB打包到.war文件中 - 这不是鲜为人知的部分 - 当我们这样做时,我们悄悄地改变了定义的java:comp/env相匹配的servlet方法.
在EJB 3.1之前,没有可能让两个EJB共享一个java:comp/env命名空间(java:comp/env在EJB规范中是bean范围的).相比之下,Servlet从来没有任何方法让各个Servlet拥有自己的私有java:comp/env命名空间(java:comp/env在Servlet规范中是模块范围的).因此在EJB 3.1中,在war中打包的EJB将具有与java:comp/envwebapp中所有其他Servlet和EJB 相同的模块范围命名空间,这与EJB在java:comp/envEAR中打包时获得的bean范围命名空间形成鲜明对比.在战争之外.我们对这个问题进行了数周辩论.
很好的一点点啤酒时间琐碎,以测试你的朋友.