Java JDBC request in a separate thread blocking block

I am having trouble understanding this. This is what happens. I am creating a new thread that maintains a JDBC connection to an Oracle database. When I ask him to connect to the database, the parent thread continues to work while the start () method is called, but when I ask the child to execute the request (using a separate method), the parent thread gets stuck waiting for the child thread to complete its work. Can I guess 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 

... ... ...

+6
source share
3 answers

I think you misunderstood how threads work. The problem is that you are calling this in the parent thread:

 myConnection.runQuery("Select * from hr.numbers order by dbms_random.value"); 

which is a sequential call to the runQuery method of myConnection , which is a stream . This does not mean that he will instruct the child to complete the method. Instead, the parent will execute it itself, and the child thread will terminate as soon as its run method returns.

If you want to have a separate thread that continues to receive commands for executing queries, you will have to implement a producer-consumer pattern, where the parent stores the queue commands for executing the child. For this, I recommend that you look at the ExecutorService .

+6
source

When you call myConnection.runQuery() , you are inside the run() method of the parent thread, so you are not in the connection thread, even if you call one of its methods.

You must call runQuery inside the run() method of myConnection to achieve what you want.

+2
source

Your runQuery method runQuery blocked, since you are calling it in the main thread (so it will wait for the request to complete). If you want it to be called on another thread, call it on another run thread (just start another thread from which you originally called the request method)

+1
source

Source: https://habr.com/ru/post/923394/


All Articles