在多线程Tomcat服务器中访问全局变量

jwe*_*gan 2 java linux openjdk multithreading tomcat

编辑:我已经发现单例的构造函数被多次调用,因此看起来这些类被单独的类加载器多次加载.如何在Tomcat中创建全局单例?我一直在谷歌搜索,但到目前为止没有运气.

我有一个像我这样构造的单例对象:

private static volatile KeyMapper mapper = null;

public static KeyMapper getMapper()
{
    if(mapper == null)
    {
        synchronized(Utils.class)
        {
            if(mapper == null)
            {
                mapper = new LocalMemoryMapper();
            }
        }
    }

    return mapper;
}
Run Code Online (Sandbox Code Playgroud)

KeyMapper类基本上是HashMap的同步包装器,只有两个函数,一个用于添加映射,另一个用于删除映射.在我的32位Windows机器上运行Tomcat 6.24时,一切正常.然而,当在64位Linux机器(带有OpenJDK 1.6.0-b09的CentOS 5.4)上运行时,我添加一个映射并打印出KeyMapper使用的HashMap的大小,以验证添加的映射(即验证大小= 1).然后我尝试用另一个请求检索映射,并且我一直变为null,当我检查HashMap的大小时它是0.我确信映射不会被意外删除,因为我已经注释掉所有要删除的调用(我不使用clear或任何其他mutators,只是获取和放置).

请求通过Tomcat 6.24(配置为使用200个线程,最少4个线程)并且我将-Xnoclassgc传递给jvm以确保类不会无意中收集垃圾(jvm也在-server模式下运行).我还为KeyMapper添加了一个finalize方法,如果它被垃圾收集以确认它没有被垃圾收集,则打印到stderr.

我在我的智慧结束,我无法弄清楚为什么一分钟HashMap中的条目存在而下一个不是:(

Sea*_*wen 5

另一个疯狂猜测:这两个请求是否可能由您的Web应用程序的不同副本提供?每个都是独立的ClassLoader,因此有一个不同的单身人士副本.