EJB容器中的ThreadLocal(和Singleton)

时间:2010-04-09 11:36:45

标签: java multithreading java-ee ejb-3.0 thread-local

我写了一个授权系统,它依赖于代表当前用户的对象。为了简化编程并提高性能,我希望在用户登录后将这些对象保存在ThreadLocal中。

看起来像这样:

public class UserCache {

    private static final ThreadLocal<User> cache = new ThreadLocal<User>();

    public User getCurrentUser() {
        return cache.get();
    }

    public void setCurrentUser(User user) {
        cache.set(user);
    }

}

我读过静态元素会使聚类出现问题。如果我在每个群集节点上都有一个UserCache,则它们都有自己的缓存对象与其他节点上的缓存对象不同步。对? UserCache是单例的经典候选者,因为应用程序只需要它的一个实例。但据我所知,@ Singleton EJB在集群中具有相同的行为。

那么如何使UserCache在EJB 3.1(Java EE 6)环境中可以集群?

从答案中提取的解决方案:

  • 使用CDI的SessionScope(JSR 299)或
  • 使用Terracotta进行JVM群集

3 个答案:

答案 0 :(得分:5)

由于您已经使用过Java EE 6,因此使用CDI(上下文和依赖注入)并不容易。这样可以将用户信息放在session scope中,并在任何地方轻松注入。 CDI为您管理其余部分。

答案 1 :(得分:1)

这不应该导致你的问题,因为线程不会跨越不同的节点 - 或者我错过了你的问题点?

编辑:您可能希望查看类似兵马俑的内容 - http://www.terracotta.org/ - 了解可以对现有对象进行聚类的方法

答案 2 :(得分:1)

如果您需要在节点之间共享对象,我还建议您查看现有的框架(如Terracotta)。

此外,使用ThreadLocal可能会导致不同的问题:

http://forums.sun.com/thread.jspa?threadID=589744 http://www.devwebsphere.com/devwebsphere/2005/06/dont_use_thread.html http://www.theserverside.com/discussions/thread.tss?thread_id=21055

但这可能不是问题。