2010-06-24 6 views
1

J'ai créé un thread avec les paramètres java.sql.Connection et String. Mais à partir de l'intérieur du thread, j'ai observé que la valeur String était disponible mais que l'objet Connection ne l'était pas. Des indices?java.sql.Connection non visible depuis un thread

(détails Modification en question):

Eh bien, il semble l'objet de connexion est disponible, mais fermé à l'intérieur du fil. Voici le code:

package com.catgen.helper; 

import java.sql.Connection; 

public class ImageCheckHelper extends Thread{ 

    public Connection conn = null; 
    public String str = null; 

    public ImageCheckHelper(Connection conn, String str){ 
     this.conn = conn; 
     this.str = str; 
     try{ 
      System.out.println("From inside the constructor"); 
      System.out.println((this.conn!=null)?"Connection is not null":"Connection is null"); 
      System.out.println((this.str!=null)?"String is not null":"String is null"); 
      System.out.println((this.conn.isClosed())?"Connection is closed.":"Connection is not closed"); 
      System.out.println("\n\n"); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    public void run(){ 
     try{ 
      System.out.println("From inside the thread"); 
      System.out.println((conn!=null)?"Connection is not null":"Connection is null"); 
      System.out.println((str!=null)?"String is not null":"String is null"); 
      System.out.println((conn.isClosed())?"Connection is closed.":"Connection is not closed"); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    public void initiateImageCheck(){ 
     this.start(); 
     return; 
    } 
} 

Et voici la sortie:

From inside the constructor 
Connection is not null 
String is not null 
Connection is not closed 



From inside the thread 
Connection is not null 
String is not null 
Connection is closed. 
+3

Non sans que vous fournissiez un code quel qu'il soit, non ... –

+0

Attention, les objets JDBC comme 'Connection',' Statement', 'ResultSet' etc. ne sont pas thread-safe en général; n'utilisez pas ces objets de plusieurs threads en même temps. Si vous avez plusieurs threads accédant à la même base de données en même temps, chaque thread aura besoin de sa propre connexion séparée. – Jesper

+0

Merci beaucoup Jesper. – James

Répondre

0

Je ne vois pas ce que votre problème est - regardant la sortie, vous pouvez voir que les deux Connection et String sont non -NULL dans le constructeur et lorsque vous venez d'exécuter le thread. La seule différence est que la connexion a été fermée à un certain point entre le thread en cours de construction et le thread en cours d'exécution. Selon la manière dont vous avez fourni la connexion et la façon dont les autres threads l'utilisaient, ce n'est pas particulièrement inhabituel. Dans tous les cas, vous devriez regarder d'autres threads en appelant close() sur le même objet Connection si vous voulez le suivre. En règle générale, il est généralement plus facile pour chaque thread de gérer sa propre connexion, car sinon vous vous retrouvez avec une sémantique très délicate sur la validation et la fermeture (comme vous l'avez vu ici). Partage d'une connexion entre plusieurs threads peut travail, et en de rares occasions est nécessaire, mais en général, il devrait être l'exception plutôt que la règle.

Éditer: En outre, beaucoup d'implémentations Connection ne sont même pas threadsafe, de sorte que vous ne pouvez pas vraiment les utiliser entre plusieurs threads d'une manière fiable. Si un thread exécute une instruction et que vous essayez ensuite d'utiliser la connexion sur un autre thread, les mauvaises choses se produiront. Encore plus de justification pour donner à chaque thread sa propre connexion et le laisser se débrouiller avec ce qu'il veut faire, sans avoir à s'engager dans une sorte de synchronisation mutex (un goulot d'étranglement qui supprime aussi une partie de l'attraction du multithreading!).

+0

Une idée comment la connexion peut-elle être rendue disponible (non fermée) à l'intérieur du fil? – James

+0

James - la seule façon de le faire est de ** ne pas fermer la connexion ailleurs **. Mais comme je l'ai dit, une meilleure solution en général est de s'assurer que chaque thread utilise sa propre connexion. –

+0

Comme vous pouvez le voir dans le code, la connexion n'est fermée explicitement nulle part. Cela semble implicite. Mon exigence ici est de créer un seul thread et de transmettre la connexion pour une utilisation ultérieure. L'utilisation du thread est de faire savoir à l'utilisateur que le processus a été lancé immédiatement après avoir lancé l'action, sans que l'utilisateur attende que l'action soit terminée. – James

0

Un autre thread ferme-t-il la connexion entre l'heure à laquelle il est donné au constructeur et l'heure à laquelle il est utilisé dans la méthode run()? Ma conjecture est que la connexion est fermée après l'appel de startsImageCheck() mais avant que la méthode run() ne soit aussi loin que la vérification isClosed().

Si non, avez-vous accès au code source du pilote JDBC? Je me demande s'il se protège contre l'utilisation multi-thread.

Les connexions ne sont pas forcément thread-safe, vous devez donc obtenir la connexion depuis le thread qui va l'utiliser.

Vous disposez également d'un accès non synchronisé à conn à partir de deux threads différents. Les variables de membre public ne sont pas non plus une bonne idée - en particulier dans les classes qui doivent être thread-safe.

+0

Vous avez le code complet devant vous. La connexion n'est pas fermée entre les deux. A propos de l'accès non synchronisé, je l'ai fait pour simplifier le code ici, car nous n'avons qu'un seul thread. – James

+0

Eh bien, immédiatement après que le thread a été créé, le flux normal utilisé pour continuer, et fermez la connexion à la fin. Merci beaucoup Richj. – James

Questions connexes