Inside a createAndShowGUI() method called by javax.swing.SwingUtilities.invokeLater like this...:
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
...I have the following piece of code which launches multiple threads with invokeLater where each threads increments the value of progBar when it is ran:
int times = 20;
for(int x = 0; x < times; x = x+1) {
new Thread("T") {
public void run() {
try {
Thread.sleep(5000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
progBar.setValue(progBar.getValue()+1);
}
});
}
}.start();
}
How can I know where all the threads are finished? If I use a counter inside invokeLater I think I will I run into race conditions.. So what is the right way to do it? Should I use a mutex? Are there some facilities provided by Swing to this purpose? Thanks.
I have implemented the code in this way according to http://www.java2s.com/Code/Java/Threads/InvokeExampleSwingandthread.htm
The Runnable
s you pass to invokeLater
are all executed on the single Event Dispatch Thread. Due to the fact that they are all sent by different threads there is no particular order but they are executed one after another.
So once you have fixed your code by moving the UI updates into the Runnable
you are passing to invokeLater
you can use Swings notification mechanism to get informed about the finishing of the jobs:
final int end=progBar.getValue() + times;
progBar.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if(progBar.getValue()==end) {
System.out.println("all jobs finished");
}
}
});
for(int x = 0; x < times; x = x+1) {
new Thread("T") {
public void run() {
try {
Thread.sleep(5000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
progBar.setValue(progBar.getValue()+1);
}
});
}
}.start();