Java Web服务中的Singleton对象

nic*_*sip 5 java singleton jax-ws

早上好,我正在开发一个公开Web服务接口的java Web应用程序.为了将全局对象保留在内存中,我将以下类用作Singleton:

public class SingletonMap {
    private static final SingletonMap instance = new SingletonMap();
    private static HashMap couponMap = null;
    private static long creationTime;

    private SingletonMap() {
        creationTime = System.currentTimeMillis();
        couponMap = new HashMap();
    }

    public static synchronized SingletonMap getInstance() {
        return instance;
    }

    public static long getCreationTime() {
        return creationTime;
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用上面的类,以便为Web服务的所有线程提供相同的HashMap实例.维护SingletonMap对象的Web服务类如下:

@WebService()
public class ETL_WS {
    private String TOMCAT_TEMP_DIR;
    private final int BUFFER_SIZE = 10000000;
    private static SingletonMap couponMap;
    private static SingletonProductMap productCategoryMap;
    private String dbTable = "user_preferences";

    public ETL_WS() {
        Context context = null;
        try {
            context = (Context) new InitialContext().lookup("java:comp/env");
            this.TOMCAT_TEMP_DIR = (String) context.lookup("FILE_UPLOAD_TEMP_DIR");
        }catch(NamingException e) {
        System.err.println(e.getMessage());
    }

    public long getCouponMapCreationTime() {
        return couponMap.getCreationTime();
    }

}
Run Code Online (Sandbox Code Playgroud)

我有方法getCouponMapCreationTime()的原因是检查Web服务的所有线程是否正在访问同一个对象.上述方法是否正确?性能开销怎么样?你认为我需要Singleton属性,还是我可以只为所有线程使用静态HashMap?如果我使用静态HashMap,如果没有线程处于活动状态,它是否会被垃圾收集?

感谢您的时间.

gga*_*iao 8

JAX-WS Web服务本身就是一个Singleton.这意味着将使用单个Web服务实例(如Servlet)处理所有请求.

因此,该类的任何成员都将在所有请求之间"共享".在您的情况下,您不需要使您的成员(即couponMap)成为静态属性.

结论:不用担心,所有线程(请求)都将访问相同的"couponMap".因为您不再需要它getCouponMapCreationTime,我认为您可以消除SingletonMap抽象并直接在Web服务类中使用Map.

但我有一些非常重要的事情要补充.如果几个线程(请求)将访问您的地图,您必须使其线程安全!有很多方法可以做到这一点,但我会提出一个想法:使用a ConcurrentHashMap而不是a HashMap.这将使您的所有get(), put(), remove()操作都是线程安全的!如果您需要更大的范围,则可以使用synchronized块,但请避免使用同步方法,因为scoop太大并且始终在this对象上进行同步.

  • 不,该对象永远不会被垃圾收集,因为框架会保留对它的引用.这些框架(servlet,jaxws等)总是保留服务对象的单个实例,但它们实际创建/销毁的是线程(使用线程池策略).但不要担心这一点,这不会影响你的内存共享数据! (2认同)
  • 我不相信@WebService实例是单例.或者,至少,不是说它必须符合规范.至少在一台JEE服务器上,情况并非如此.事实上,这似乎意味着规范是针对JAX-WS服务*不*是单身:http://stackoverflow.com/a/7010266/796761 (2认同)