我已经在stackoverflow上阅读了EJB的限制和几个答案,但我不太确定我在工作中发现的一段代码。
有一项服务可根据标识符提供有关Foos的详细信息。
public FooResponse getFoo(FooRequest request){...};
表面下的某个地方是一个自写池,它保存最近提供的响应对象。对于每个请求,如果有可用的条目,则会询问池。如果是,则将其用作响应,如果不是,则将询问数据库。从数据库中获取响应时,它将存储在池中。
游泳池使用两种策略来照顾它的大小。
首先,它使用java.lang.ref.SoftReference<T>
内的Map
来避免OutOfMemoryError
。
它使用的第二件事是java.util.TimerTask
,它是为Map
中的每个条目创建的,并由java.util.Timer
调度,在可配置的时间后删除条目。
在我看来,这违反了限制,不允许EJB创建线程(java.util.Timer
执行)。我是对的还是我错过了什么?
直到今天,这还没有引起任何明显的问题。你建议,摆脱这个自编码池吗?
另一件事是,该服务是无状态的SessionBean。容器不仅会创建其中一个容器。因此,他们不会共享同一个池,如果一个bean被问及Foo
两次,那就很幸运。我也是对的吗?
答案 0 :(得分:2)
创建自己的线程的主要问题是它意味着它们不在应用程序服务器的控制之下,这可能导致流氓EJB通过创建太多线程来“破坏服务器”。
但是,拥有后台线程是理想的事情,因此通常app服务器提供“工作管理器”以便安排任务(使用计时器或并行线程)。
这是一篇关于CommonJ with Websphere的文章,它提供了如何在不破坏服务器的情况下使用线程的背景知识:Work Managers
以下是Weblogic的CommonJ文档:The Timer and Work Manager API
虽然可能偏离主题,但春天如何与工作经理进行整合:Task Execution and Scheduling
要解决您的问题,我会集成一个缓存(例如EHCache)并让它解决何时从缓存中逐出项目。
(同样,可能偏离主题,使用Spring,可以使用缓存来为代码添加一些注释:ehcache-spring-annotations)