java.sql.Connection not visible from within a thread
I created one thread with java.sql.Connection and String parameters. But from within the thread, I observed that String value was available but Connection object was not. Any clues?
(Editing details into question):
Well, it seems the connection object is available, but closed inside the thread. Here's the 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;
}
开发者_开发百科}
And here's the output:
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.
Is another thread closing the connection between the time it is given to the constructor and the time it is used in the run() method? My guess is that the connection is closed after the call to initiateImageCheck() returns but before the run() method has got as far as the isClosed() check.
If not, do you have access to the JDBC driver's source code? I wonder if it is protecting itself against multi-threaded use.
Connections are not guaranteed to be thread-safe, so you should obtain the connection from within the thread that is going to use it.
You also have unsynchronized access to conn from two different threads. Public member variables are not a good idea either - especially in classes that need to be thread-safe.
I don't see what your problem is - looking at the output, you can see that both the Connection
and String
are non-null within the constructor and when you come to run the thread.
The only difference is that the connection has been closed at some point between the thread being constructed, and the thread being run. Depending on how you provided the connection, and how other threads were using it, this is not particularly unusual. In any case, you should be looking at other threads calling close()
on the same Connection object if you want to track this down.
As a general guideline, it's typically easiest to have each thread manage its own Connection, because otherwise you end up with some very tricky semantics about committing and closing them (as you've seen here). Sharing a connection between multiple threads can work, and on rare occasions is necessary, but in general it should be the exception rather than the rule.
Edit: Additionally, a lot of Connection
implementations are not even threadsafe, so you can't really use them between multiple threads in a reliable fashion. If one thread is running a statement and you then try to use the connection on a different thread, bad things will happen. Even more justification to just give each thread its own connection and let it get on with what it wants to do, without having to engage in some kind of mutex synchronization (a bottleneck that removes some of the attraction of multithreading, too!).
精彩评论