Lors de l'utilisation d'une connexion de base de données locale de thread, la fermeture de la connexion est requise lorsque le thread existe.Comment forcer un thread Java à fermer une connexion de base de données locale de thread
Je ne peux le faire que si je peux remplacer la méthode run() du thread appelant. Même ce n'est pas une bonne solution, car au moment de la sortie, je ne sais pas si une connexion a déjà été ouverte par ce thread.
Le problème est en fait plus général: Comment forcer un thread à appeler une méthode de finalisation d'un objet thread-local quand il se termine.
J'ai regardé les sources de java 1.5 et trouvé que la carte locale de thread est définie sur null, ce qui entraînera éventuellement la garbage collection à appeler finalize(), mais je ne veux pas compter sur les ordures collectionneur.
La dérogation suivante semble inévitable de se assurer qu'une connexion de base de données est fermée:
@Override
public void remove() {
get().release();
super.remove();
}
où version() ferme la connexion de base de données, si elle a été ouverte. Mais nous ne savons pas si le thread a déjà utilisé ce thread-local. Si get() n'a jamais été appelé par ce fil, alors il est tout à fait un gaspillage d'efforts ici: ThreadLocal.initialValue() sera appelée, une carte sera créée sur ce fil, etc.
-
d'autres précisions et exemple selon le commentaire de Thorbjørn:
java.lang.ThreadLocal est un type d'usine pour un objet qui est lié à un fil. Ce type a un getter pour l'objet et une méthode d'usine (typiquement écrite par l'utilisateur). Lorsque le getter est appelé, il appelle la méthode factory uniquement s'il n'a jamais été appelé auparavant par ce thread.
L'utilisation de ThreadLocal permet à un développeur de lier une ressource à un thread même si le code de thread a été écrit par un tiers. Exemple: Exemple: Disons que nous avons un type de ressource appelé MyType et que nous voulons en avoir un et un seul par thread.
Définir dans la classe en utilisant: private static ThreadLocal resourceFactory = new ThreadLocal() { @Override protégé MyType initialValue() {return new MyType(); }}
utilisation dans le contexte local dans cette classe: public void someMethod() { MyType ressources = resourceFactory.get(); resource.useResource(); }
get() peut appeler initialValue() une seule fois dans le cycle de vie du fil d'appel. À ce stade, une instance de MyType est instanciée et liée à ce thread. Les appels suivants à get() par ce fil se réfèrent à nouveau à cet objet.
L'exemple d'utilisation classique est lorsque MyType est un formateur de texte/date/xml peu sûr.
Mais ces formatteurs habituellement ne doivent pas nécessairement être libéré ou fermé, les connexions de base de données et je ne me sers java.lang.ThreadLocal d'avoir une connexion d'une base de données par thread. La façon dont je le vois, java.lang.ThreadLocal est presque parfait pour cela. Presque parce qu'il n'y a aucun moyen de garantir la fermeture de la ressource si le thread appelant appartient à une application tierce.
J'ai besoin de vos cerveaux: En étendant java.lang.ThreadLocal J'ai réussi à lier une connexion de base de données pour chaque thread, pour son usage exclusif - y compris les threads que je ne peux pas modifier ou remplacer. J'ai réussi à m'assurer que les connexions soient fermées au cas où le thread meurt sur une exception non interceptée.
En cas de sortie de fil normale, le ramasse-miettes ferme la connexion (parce que MyType remplace la finalisation ()). En réalité, cela arrive assez rapidement, mais ce n'est pas idéal.
Si j'avais mon chemin, il y aurait eu une autre méthode sur la java.lang.ThreadLocal:
protected void release() throws Throwable {}
Si cette méthode existait sur java.lang.ThreadLocal, appelé par machine virtuelle Java sur n'importe quel fil de sortie/mort, alors dans mon propre override je pourrais fermer ma connexion (et le rédempteur serait venu à Sion). En l'absence d'une telle méthode, je suis à la recherche d'une autre façon de confirmer la fermeture.
Une méthode qui ne dépendra pas de la récupération de place JVM.
Merci
S'il vous plaît ajouter un code minimal montrant ce que vous décrivez. De préférence, runnable. –
Ajout de code. Espérons que cela explique l'un des problèmes. –
Eh bien, non. Veuillez créer un exemple fonctionnel minimal. –