辛格尔顿对象中的Java Web服务(Singleton Object in Java Web se

2019-06-25 14:36发布

早上好,我目前正在开发一个公开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;
    }
}

我才能有HashMap中的同一个实例为Web服务的所有线程使用上述类。 即保持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();
    }

}

其原因我有方法getCouponMapCreationTime()是检查web服务的所有线程都访问同一个对象。 是上面的方法正确吗? 怎么样性能方面的开销? 你觉得我需要的单身属性,或者我可以只使用所有线程静态HashMap的? 如果我使用一个静态HashMap中,莫非要被垃圾收集的情况下,没有线程处于活动状态?

感谢您的时间。

Answer 1:

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

所以,类的任何成员将所有请求之间“共享”。 在你的情况,你不需要让你的会员(即couponMap)的静态属性。

结论:别担心,你的所有线程(请求)访问相同的“couponMap”。 因为你不需要getCouponMapCreationTime了,我认为你可以消除SingletonMap抽象并在Web服务类直接使用的地图。

但是,我有一些非常重要的补充。 如果有多个线程(请求)访问你的地图,你必须使它线程安全的! 有很多的方式来做到这一点,但我会给一个想法:使用ConcurrentHashMap代替的HashMap 。 这将使所有的get(), put(), remove()操作是线程安全的! 如果你需要一个更大的范围,你可以使用synchronized块,但请避免同步方法,因为舀过大,始终同步在this对象。



Answer 2:

JAX-WS拥有自己创建单身的模式,你不需要使用静态字段。 您可以使用@Inject注释到每个服务。 看到这个博客帖子: http://weblogs.java.net/blog/jitu/archive/2010/02/19/jax-ws-cdi-java-ee-6-0 (但不使用@SessionScoped ,使用@Singleton

其他的一些要点:

  1. HashMap是不是线程安全的,你需要ConcurrentHashMap

  2. catch(NamingException e) { System.err.println(e.getMessage()); 是无益的。 重新抛出的RuntimeException 。 你不能从中恢复。

  3. 不要担心在这个阶段的性能开销。 衡量它,一旦你有什么工作。



文章来源: Singleton Object in Java Web service