Singleton-Objekt im Java-Web-service
Guten morgen,
Ich bin derzeit an der Entwicklung einer java web-Anwendung stellt einem web-service-Schnittstelle. Um ein globales Objekt im Speicher nutze ich die folgende Klasse als 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;
}
}
Ich bin mit der obigen Klasse haben, um die gleiche Instanz von HashMap für alle threads des web-service. Die Web service-Klasse, die behauptet, die SingletonMap-Objekt ist die folgende:
@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();
}
}
Den Grund habe ich die Methode getCouponMapCreationTime() ist zu prüfen, ob alle threads des web-service-Zugriff auf das gleiche Objekt. Ist die obige Vorgehensweise korrekt? Wie etwa performance-Overhead? Glaubst du, ich brauche die Singleton-Eigenschaften, oder könnte ich nur eine statische HashMap für alle threads? Wenn ich eine statische HashMap, wird es von der garbage Collection freigegeben, wenn keine Threads aktiv ist?
Vielen Dank für Ihre Zeit.
InformationsquelleAutor nick.katsip | 2012-06-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einen JAX-WS web service ist durch sich selbst ein Singleton. Dies bedeutet, dass alle die Anfrage wird direkt über einen einzigen web-service-Instanz (wie ein Servlet).
So, jedes Mitglied der Klasse werden die 'gemeinsame' zwischen all den Wunsch. In Ihrem Fall, Sie nicht brauchen, um Ihre Mitglieder (d.h. couponMap) eine statische Attribute.
Fazit: keine Sorge, alle deine threads (Anfrage) werden Zugriff auf die gleichen 'couponMap'. Da brauchen Sie nicht die
getCouponMapCreationTime
mehr, ich denke, dass können Sie beseitigen dieSingletonMap
Abstraktion und die Nutzung direkt eine Karte in Ihrem web-service-Klasse.Aber ich habe etwas sehr wichtiges hinzufügen. Wenn mehrere threads (Anfrage) wird der Zugriff auf Ihre Karte, die Sie haben, um es thread-sicher ist sicher!!! Es gibt viele Weg, dies zu tun, doch ich habe eine Idee: Verwenden Sie eine
ConcurrentHashMap
statt einerHashMap
. Dies wird alle Ihreget(), put(), remove()
Operationen thread-sicher! Wenn Sie benötigen eine größere Reichweite können Sie verwenden, synchronisiert Blöcke, aber bitte vermeiden Sie synchronisieren Methoden, weil die Schaufel ist zu groß und synchronisieren Sie immer überthis
Objekt.Nein, das Objekt wird nie Müll gesammelt, da das framework hält eine Referenz darauf. Diese Art von frameworks (servlet, jaxws, etc) immer eine einzige Instanz des service-Objekt, aber das, was Sie eigentlich erschaffen/zerstören ist threads (mit thread-pool-Richtlinien). Aber machen Sie sich keine Sorge, dies wird keine Auswirkungen auf Ihre in-memory-shared-data!!!
Danke ggarciao. Eure schnellen Antworten hat mir sehr geholfen.
Sorry, dich wieder zu stören, aber ich habe versucht die Deklaration der privaten ConcurrentHashMap couponMap; (und sogar als ein statisch), aber es scheint, dass das Objekt stirbt, wenn ein client erhält seine Antwort.
Ich glaube nicht, es ist wahr, dass eine @WebService-Instanz ist ein singleton. Oder, mindestens, nicht, dass es wahr sein muss, pro spec. Und zumindest auf einem JEE-server, ist es nicht wahr. In der Tat, dies scheint zu implizieren, dass die norm ist für einen JAX-WS-service für nicht ein singleton: stackoverflow.com/a/7010266/796761
InformationsquelleAutor ggarciao
JAX-WS hat seine eigenen Muster für die Erstellung von singletons, die Sie nicht brauchen, um die Verwendung von statischen Feldern. Verwenden Sie die
@Inject
annotation in jeden Dienst. Dieser blog-post: http://weblogs.java.net/blog/jitu/archive/2010/02/19/jax-ws-cdi-java-ee-6-0 (aber nicht verwenden@SessionScoped
verwenden@Singleton
)Einige andere Punkte:
HashMap
ist nicht thread-sicher, die Sie benötigenConcurrentHashMap
.Diese
catch(NamingException e) { System.err.println(e.getMessage());
ist wenig hilfreich. Rethrow es alsRuntimeException
. Sie können nicht wiederhergestellt werden.Mach dir keine sorgen über performance-overhead in diesem Stadium. Messen Sie, wenn Sie einmal etwas arbeiten.
InformationsquelleAutor artbristol