Sunday, August 19, 2012

Be careful with Java Thread.join() in GUI design

I was stuck by a problem for about a week. Every time I tried to run the GUI,the GUI was frozen, no buttons, menus or any other operations could be done until all the back-end computations finished.
Finally I figured out the cause of the problem. Since I'm using parallel programming. I created a thread when a new transaction was required, and I joined all the threads when they finished. I created threads with following code:


Thread threadArray[] = new Thread[testThreadNmuber];
for(int i=0; i<testThreadNmuber; i++)
{
    threadArray[i] = new Thread(testDriver);
    threadArray[i].start();  
}

Above code worked fine. I thought I should be able to use the similar way to join the threads. Therefore I wrote following code:

for(int i=0; i<testThreadNmuber; i++)
{
    threadArray[i].join();
    System.out.println("Thread-" +i+ " : exited\n");
}
However, the join() function caused a critical error. I didn't realize the problem of join(), because it was the common way to implement in Java parallel programming. While I understood the problem by reading the Java API. In Java API the explanation of join() is 'Waits for this thread to die'. As I called the join() in the main thread, the main thread would wait for all the sub-threads to die. In GUI design, the main thread is the thread that draw the interface. If the interface waits all the sub-threads to die the main thread will hold up and the interface will not response any operations. Therefore, I should not use join() in GUI programming.


However this cause another problem. If I don't use join(), how I can know if all the jobs finish? One simple solution is to create a integer, if one thread finish, the integer plus one. When this integer is equal to the number of threads, all the thread finish. But this integer must be locked when one thread is updating it, otherwise the race condition may occur.


No comments:

Post a Comment