Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infinite loop in exiting a thread using thread pool

I'm working in a code that employ multithreading. The concerned piece of code is in the following structure:

try {
    ExecutorService threadExecutor = Executors.newFixedThreadPool(10);

    while (resultSet.next()) {
        name = resultSet.getString("hName");
        MyRunnable worker = new Myrunnable(name);
        threadExecutor.execute(worker);
        Counter++;
    }

    //This never appears
    System.out.println("End while with counter" + Counter);

    threadExecutor.shutdown();
    System.out.println("thread shutdown"); //this never appears

    // Wait until all threads are finish
    while (!threadExecutor.isTerminated()) {
        threadExecutor.awaitTermination(1, TimeUnit.SECONDS);
        System.out.println("inside the thread termination loop."); //I have infinite loop

    }

    System.out.println("Finished all threads"); //never appears

} catch (Exception e) {
    e.printStackTrace();
}

System.out.println("END MAIN");

DBConnection.con.close();

The run function ends for sure. The last name in my DB executes the required function and its thread ends.

//The constructor
MyRunnable (String name)  {
    this.name=name;
}

public void run() {
    myclass Obj=new myclass();
    try {
        Obj.myFunction(name);
    } catch (Exception e) {
        System.out.println("Got an Exception: "+e.getMessage());
    }
    System.out.println(" thread exiting" + this.name);
}

My problem is that my program executes everything correctly except that at the last thread, I see the "thread exiting" with the the last name from the DB. But the threadexecutor never shuts down and the program enters an infinite loop.

EDIT

Here is the code in the main that extracts names from the DB.

try {
        st = DBConnection.con.createStatement();

        resultSet = st.executeQuery("select hName from schema1.table1  where checked=1 order by hName");

    } catch (Exception e) {
        System.out.println("DB Error: " + e.getMessage());

    }
like image 406
Jury A Avatar asked Jul 12 '26 15:07

Jury A


1 Answers

Here is my best guess at what's going on:

First off, I suspect that these two comments:

//This never appears
System.out.println("End while with counter" + Counter);

threadExecutor.shutdown();
System.out.println("thread shutdown"); //this never appears

are incorrect. I strongly suspect that in fact you do get those messages, but they're mixed in with your other messages (such as the "thread exiting" message) so you miss them.

Secondly, I suspect that sometimes, Obj.myfunction(name) hangs. This is especially likely if Obj.myfunction involves writing back to the database - it'll work correctly most of the time, but every now and then (and more likely with more rows) you'll hit a database deadlock. So, in fact, you aren't getting the "Thread exited" message for every name, but finding the one or two in the middle of the list that don't give you that message is going to be difficult.

To determine if this is the case, I would generate a thread dump of your java program while it's sitting in the infinite loop. On Unix/Mac, you do this by opening up another window and doing kill -3 PID, where PID is the process ID of your java process. In Windows, I think that the key combination you need to use is Ctrl-Break. In the tread dump, look to see if the threadpool's worker threads are stuck inside the call to Obj.myfunction.

One possible source of the database deadlock is that you don't close your ResultSet until you close the database connection itself at the end of the program. I would add a call to

resultSet.close();

right after your while loop ends, and just before you print out your message about "End while with counter". If you still see database deadlocks happening even after you add that statement, then you'll have to ask a different question focused on what that function myfunction is doing.

like image 163
Daniel Martin Avatar answered Jul 14 '26 04:07

Daniel Martin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!