Java JDBC query in separate thread lock parent
java, jdbc, multithreading, oracle
Solution
I think you have misunderstood a bit how threads work. The problem is that you are calling this on the parent thread:
myConnection.runQuery("Select * from hr.numbers order by dbms_random.value");
which is a sequential invocation of the `runQuery` method on the `myConnection` object that happens to be a thread. This does not mean that it will instruct the child to execute the method. Instead the parent will execute it itself and the child thread finishes as soon as its `run` method has returned.
If you want to have a separate thread that keeps receiving commands to execute queries you will have to implement a producer-consumer pattern, where the parent keeps queuing commands for the child to execute. To this end I recommend you look at ExecutorService.
Problem
I'm having some trouble understanding this. Here's what's happening. I'm spawning a new thread that holds a JDBC connection to a Oracle database. When I ask it to connect to the database, the parent thread keeps running while the start() method is invoked but when I ask the child to execute a query (on a separate method), the parent thread gets stuck waiting for the child thread's method to finish doing its work. Any guess as how to fix this? Thanks in advance! ``` 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; } ``` Here's the output I get: ``` 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 ``` ... ... .. .