我在理解这个问题上遇到了一些麻烦。 这是正在发生的事情。 我正在生成一个新的线程,它保存与Oracle数据库的JDBC连接。 当我要求它连接到数据库时,父线程在调用start()方法时继续运行但是当我要求子进行查询时(在单独的方法上),父线程被卡住等待子线程的完成工作的方法。 有什么猜测如何解决这个问题? 提前谢谢!
public class Main extends Thread{
public Main()
{
}
public void myCounter() {
int i = 0;
DBConnection myConnection = null;
for(;;)
{
i++;
System.out.println("time: " + i);
if( i == 5)
{
myConnection = new DBConnection("localhost", 1521, "hr", "hr", "XE");
myConnection.start();
}
if(i == 10)
try {
myConnection.runQuery("Select * from hr.numbers order by dbms_random.value");
} catch (SQLException e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void run()
{
myCounter();
}
public static void main(String[] args) {
Main boot = new Main();
boot.start();
}
}
public class DBConnection extends Thread{
Connection myConnection;
int port;
String user;
String password;
String serviceName;
String host;
public void run()
{
setUpConnection(host, port, user, password, serviceName);
}
/**
* Sets up variables to create a connection to Oracle.
*
* @param host host
* @param port port
* @param user user
* @param password password
*/
public DBConnection(String host, int port, String user, String password, String serviceName)
{
this.host = host;
this.port = port;
this.user = user;
this.password = password;
this.serviceName = serviceName;
}
private void setUpConnection(String host, int port, String user,
String password, String dataBase) {
System.out.println("-------- Oracle "
+ "JDBC Connection Testing ------------");
try {
Class.forName("oracle.jdbc.OracleDriver");
} catch (ClassNotFoundException e) {
System.out.println("Couldn't find Oracle JDBC Driver... :-(");
e.printStackTrace();
return;
}
System.out.println("Oracle JDBC Driver Registered!");
myConnection = null;
try {
myConnection = DriverManager.getConnection(
"jdbc:oracle:thin:@//"
+ host
+ ":"
+ port
+ "/"
+ dataBase,
user, password
);
} catch (SQLException e) {
System.out.println("Connection Failed!");
e.printStackTrace();
return;
}
if (myConnection != null) {
System.out.println("Connected to Oracle! :-)");
} else {
System.out.println("Failed to make connection!");
}
}
/**
* Queries the database and returns a ResultSet
* @param query SQL
* @throws SQLException
*/
public ResultSet runQuery(String query) throws SQLException
{
System.out.println(" [DBConnection] Started Running @ " + (new SimpleDateFormat("HH:mm:ss:S")).format(new Date()));
ResultSet rs = null;
Statement stt = myConnection.createStatement();
rs = stt.executeQuery(query);
System.out.println(" [DBConnection] Finished Running @: " + (new SimpleDateFormat("HH:mm:ss:S")).format(new Date()));
return rs;
}
这是我得到的输出:
time: 1
time: 2
time: 3
time: 4
time: 5
-------- Oracle JDBC Connection Testing ------------
Oracle JDBC Driver Registered!
time: 6
Connected to Oracle! :-)
time: 7
time: 8
time: 9
time: 10
[DBConnection] Started Running @ 14:46:00:660
[DBConnection] Finished Running @: 14:46:12:750
time: 11
time: 12
time: 13
time: 14
... ... ..
答案 0 :(得分:6)
我认为你误解了线程的工作原理。问题是你在父线程上调用它:
myConnection.runQuery("Select * from hr.numbers order by dbms_random.value");
这是对runQuery
对象上恰好是线程的myConnection
方法的顺序调用。这并不意味着它会指示孩子执行该方法。相反,父级将自己执行它,并且子级线程在其run
方法返回后立即完成。
如果您希望有一个单独的线程继续接收执行查询的命令,则必须实现生产者 - 消费者模式,其中父级保持排队命令以便子项执行。为此,我建议您查看ExecutorService。
答案 1 :(得分:2)
当您调用myConnection.runQuery()
时,您位于父线程的run()
方法内,因此即使您调用其中一种方法,也不在connection
线程中。
您应该在runQuery
的{{1}}方法中调用run()
来实现您的目标。
答案 2 :(得分:1)
您的runQuery
方法阻塞,因为您在主线程上调用它(因此它将等待查询完成)。如果你想在另一个线程上调用它,请在另一个线程run
方法上调用它(只需启动你最初调用查询方法的另一个线程)