Singleton Object in Java Web Service

Good morning, I am currently developing a Java application that provides a web service interface. To save the global object in memory, I use the following class as 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; } } 

I use the above class to have the same HashMap instance for all web service threads. The Web service class that supports the SingletonMap object is as follows:

 @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(); } } 

The reason I have the getCouponMapCreationTime () method is to check that all web service threads are accessing the same object. Is this approach correct? What about performance overhead? Do you think I need Singleton properties, or can I use a static HashMap for all threads? If I use a static HashMap, is it going to collect garbage in case the thread is not active?

Thank you for your time.

+4
source share
2 answers

The JAX-WS web service itself is Singleton. This means that the entire request will be processed using one instance of the web service (for example, a servlet).

Thus, any member of the class will be "shared" between all requests. In your case, you do not need to set your members (i.e. couponMap) static attributes.

Conclusion: don't worry, all your threads (request) will access the same "couponMap". Since you no longer need getCouponMapCreationTime , I think you can eliminate the SingletonMap abstraction and use the map directly in your web services class.

But I have something very important to add. If several threads (request) will access your card, you must make it thread safe !!! There are many ways to do this, but I will give an idea: use ConcurrentHashMap instead of HashMap . This will make all your get(), put(), remove() operations thread safe! If you need a wider scope, you can use synchronized blocks, but please avoid synchronizing methods because the scoop is too large and always synchronizes with the this object.

+7
source

JAX-WS has its own templates for creating singleton, you do not need to use static fields. You use the @Inject annotation in each service. See this blog post: http://weblogs.java.net/blog/jitu/archive/2010/02/19/jax-ws-cdi-java-ee-6-0 (but don't use @SessionScoped , use @Singleton )

Some other points:

  • HashMap not thread safe, you need ConcurrentHashMap .

  • This catch(NamingException e) { System.err.println(e.getMessage()); is useless. Repeat this as a RuntimeException . You cannot recover from it.

  • At this point, do not worry about workloads. Measure it as soon as you have something working.

+3
source

All Articles