Singleton Objet dans Java Web service
Bon matin,
Je suis en train de développer une application web java qui expose une interface de service web. Afin de garder un objet global dans la mémoire, j'utilise la classe suivante comme un 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;
}
}
Je suis à l'aide de la classe ci-dessus afin d'avoir la même instance de la table de hachage pour tous les threads du service web. La classe de service Web qui maintient la SingletonMap objet est le suivant:
@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();
}
}
La raison pour laquelle j'ai la méthode getCouponMapCreationTime() est de vérifier que tous les fils de la toile de service ont accès au même objet. Est l'approche ci-dessus est correcte? Comment sur les performances des frais généraux? Pensez-vous j'ai besoin de le Singleton propriétés, ou pourrais-je utiliser une table de hachage statique pour tous les threads? Si j'utilise une table de hachage statique, est-ce que ça va être des ordures collectées dans le cas où aucun fil est active?
Je vous remercie pour votre temps.
OriginalL'auteur nick.katsip | 2012-06-19
Vous devez vous connecter pour publier un commentaire.
Un JAX-WS service web est un Singleton. Cela signifie que toutes les demandes seront traitées à l'aide d'une seule instance du service web (comme un Servlet).
Donc, n'importe quel membre de la classe sera partagée entre tous les la demande. Dans votre cas, vous n'avez pas besoin de faire de vos membres (c'est à dire couponMap) les attributs statiques.
Conclusion: Ne vous inquiétez pas, tous vos threads (demande) accèdent à la même "couponMap'. Parce que vous n'avez pas besoin de la
getCouponMapCreationTime
plus, je pense que vous pouvez éliminer leSingletonMap
l'abstraction et de l'utiliser directement une Carte dans votre classe de service web.Mais j'ai quelque chose de très important à ajouter. Si plusieurs threads (demande) pourront accéder à votre Carte, vous devez le rendre thread-safe!!! Il y a beaucoup de façon de le faire, mais je vais vous donner une idée: Utiliser un
ConcurrentHashMap
au lieu d'unHashMap
. Cela rendra tous vosget(), put(), remove()
opérations thread-safe! Si vous avez besoin d'une plus grande portée, vous pouvez utiliser des blocs synchronisés, mais s'il vous plaît éviter de synchroniser les méthodes, car le scoop est trop grande et toujours synchroniser surthis
objet.Non, l'objet sera jamais ordures collectées, parce que le cadre conserve une référence à elle. Ces types de cadres (servlet, jaxws, etc) toujours garder qu'une seule instance de l'objet du service, mais ce qu'ils ont réellement créer/détruire des threads (à l'aide de pool de threads politiques). Mais ne vous inquiétez pas à ce sujet, ce sera sans aucun impact sur votre mémoire de données partagée!!!
Merci ggarciao. Rapidité de vos réponses m'ont beaucoup aidé.
Désolé de vous déranger à nouveau, mais j'ai essayé de déclarer le privé ConcurrentHashMap couponMap; (et même en statique), mais il semble que l'objet meurt à chaque fois qu'un client reçoit sa réponse.
Je ne crois pas que c'est vrai qu'un @WebService instance est un singleton. Ou, au moins, pas que ça doit être vrai par la spécification. Et au moins sur un serveur JEE, il n'est pas vrai. En fait, cela semble impliquer que la norme est un JAX-WS service de pas être un singleton: stackoverflow.com/a/7010266/796761
OriginalL'auteur ggarciao
JAX-WS a ses propres modèles pour la création de singletons, vous n'avez pas besoin d'utiliser des champs statiques. Vous utilisez le
@Inject
annotation dans chaque service. Consultez cet article de blog: http://weblogs.java.net/blog/jitu/archive/2010/02/19/jax-ws-cdi-java-ee-6-0 (mais ne pas utiliser de@SessionScoped
, utilisez@Singleton
)Quelques autres points:
HashMap
n'est pas thread-safe, vous avez besoinConcurrentHashMap
.Ce
catch(NamingException e) { System.err.println(e.getMessage());
est inutile. Renvoyer comme unRuntimeException
. Vous ne pouvez pas la récupérer.Ne vous inquiétez pas à propos de la surcharge de performances à ce stade. Mesurer une fois que vous avez quelque chose à travailler.
OriginalL'auteur artbristol