-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
6
-
x86
-
linux
FULL PRODUCT VERSION :
java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b05)
Java HotSpot(TM) Client VM (build 1.6.0_02-b05, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux 2.6.9 #1 SMP Thu Oct 4 19:13:07 CEST 2007 i686 i686 i386 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The SwingWorker documentation says that the 'done()' method is executed in the EDT after the 'doInBackground()' method has been executed. If in 'doInBackground()' I submit a task to the EDT using 'invokeLater()' I would expect this task to be executed before the 'done()' execution. This is what happens most of the times but not always.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the reported code passing an integer as argument.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
From the execution of the above code I would expect for each TestSW object the line starting with "2" being printed before lines starting with "1" (look at the time stamp too).
ACTUAL -
The results are what I expect if the program is executed passing as argument a small integer (< 1000). Using higher numbers (i.e., 3000) for some TestSW objects the lines starting with "2" are printed before lines starting with "1". This is not a buffer flushing problem (look at the time stamps).
REPRODUCIBILITY :
This bug can be reproduced occasionally.
---------- BEGIN SOURCE ----------
import javax.swing.*;
import java.util.*;
import java.lang.*;
public class TestOrder {
private TestSW worker;
class TestSW extends SwingWorker<Boolean, Void> {
private final String msg;
TestSW(String msg) {
super();
this.msg = msg;
}
protected Boolean doInBackground() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
System.err.println("1 - " + TestSW.this.msg + " - " + new Date().getTime());
System.err.flush();
}
});
return Boolean.TRUE;
}
protected void done() {
try {
this.get();
System.err.println("2 - " + TestSW.this.msg + " - " + new Date().getTime());
System.err.flush();
}
catch(Exception ex) {
}
}
}
TestOrder(String msg) {
this.worker = new TestSW(msg);
}
public void start() {
this.worker.execute();
}
public void waitForTermination() {
try {
this.worker.get();
}
catch(Exception ex) {
}
}
public static void main(String[] args) {
while(true) {
final Vector<TestOrder> vect = new Vector<TestOrder>();
final int size = Integer.parseInt(args[0]);
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
for(int i = 0; i < size; i++) {
vect.add(new TestOrder(new Integer(i).toString()));
}
for(int i = 0; i < size; i++) {
vect.get(i).start();
}
for(int i = 0; i < size; i++) {
vect.get(i).waitForTermination();
}
}
});
System.err.flush();
Thread.sleep(1000);
System.err.println("Sleeping before starting new cycle...");
System.err.flush();
Thread.sleep(1000);
}
catch(Exception ex) {
System.err.println(ex);
}
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
As a workaround the 'invokeLater()' method can be used in the 'done()' method. Or 'invokeAndWait()' instead of 'invokeLater()' can be used in 'doInBackground()'.
java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b05)
Java HotSpot(TM) Client VM (build 1.6.0_02-b05, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux 2.6.9 #1 SMP Thu Oct 4 19:13:07 CEST 2007 i686 i686 i386 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The SwingWorker documentation says that the 'done()' method is executed in the EDT after the 'doInBackground()' method has been executed. If in 'doInBackground()' I submit a task to the EDT using 'invokeLater()' I would expect this task to be executed before the 'done()' execution. This is what happens most of the times but not always.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the reported code passing an integer as argument.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
From the execution of the above code I would expect for each TestSW object the line starting with "2" being printed before lines starting with "1" (look at the time stamp too).
ACTUAL -
The results are what I expect if the program is executed passing as argument a small integer (< 1000). Using higher numbers (i.e., 3000) for some TestSW objects the lines starting with "2" are printed before lines starting with "1". This is not a buffer flushing problem (look at the time stamps).
REPRODUCIBILITY :
This bug can be reproduced occasionally.
---------- BEGIN SOURCE ----------
import javax.swing.*;
import java.util.*;
import java.lang.*;
public class TestOrder {
private TestSW worker;
class TestSW extends SwingWorker<Boolean, Void> {
private final String msg;
TestSW(String msg) {
super();
this.msg = msg;
}
protected Boolean doInBackground() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
System.err.println("1 - " + TestSW.this.msg + " - " + new Date().getTime());
System.err.flush();
}
});
return Boolean.TRUE;
}
protected void done() {
try {
this.get();
System.err.println("2 - " + TestSW.this.msg + " - " + new Date().getTime());
System.err.flush();
}
catch(Exception ex) {
}
}
}
TestOrder(String msg) {
this.worker = new TestSW(msg);
}
public void start() {
this.worker.execute();
}
public void waitForTermination() {
try {
this.worker.get();
}
catch(Exception ex) {
}
}
public static void main(String[] args) {
while(true) {
final Vector<TestOrder> vect = new Vector<TestOrder>();
final int size = Integer.parseInt(args[0]);
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
for(int i = 0; i < size; i++) {
vect.add(new TestOrder(new Integer(i).toString()));
}
for(int i = 0; i < size; i++) {
vect.get(i).start();
}
for(int i = 0; i < size; i++) {
vect.get(i).waitForTermination();
}
}
});
System.err.flush();
Thread.sleep(1000);
System.err.println("Sleeping before starting new cycle...");
System.err.flush();
Thread.sleep(1000);
}
catch(Exception ex) {
System.err.println(ex);
}
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
As a workaround the 'invokeLater()' method can be used in the 'done()' method. Or 'invokeAndWait()' instead of 'invokeLater()' can be used in 'doInBackground()'.