Waiting (nicely!) for a thread

S

Simon Andrews

I'm writing a class which can include a long IO-bound routine and I'm
trying to show a progress bar during the loading of this data. I've
separated the IO code into a seaprate thread which puts up a progress
pane to show what it's doing. This bit all works.

The problem is that my class returns a big data structure. Initially
this is empty and it is loaded dynamically the first time it's asked for
(using the separate threaded code). Subsequent calls use the pre-loaded
data and return quickly without doing the IO again.

The problem is how to get the call to the thread to wait for it to
complete before passing back the data structure. The code I'm using is
shown below. This works, but doesn't allow the window produced by
ProgressWindow to update. If I remove the while (!done) code the
progess window updates OK (and the data is loaded), but this method
returns instantly with a null value.

How can I make this method wait nicely for ProgressWindow to complete
whilst still allowing GUI updates to happen?

Cheers

Simon.

public Species [] getSpeciesOntology (Component c) throws IOException {
if (speciesList == null) {
// ProgressWindow is a new thread
ProgressWindow w = new ProgressWindow(c);

while (!w.done) {
System.err.println("Still waiting....");
try {
Thread.sleep(1000);
}
catch (Exception e) {

}
}
}
return speciesList;
}
 
J

jan V

How can I make this method wait nicely for ProgressWindow to complete
whilst still allowing GUI updates to happen?

How about Thread's join()... and how about reading up on such basics before
posting? There's plenty of free books and tutorials out there...
 
T

Thomas G. Marshall

jan V coughed up:
How about Thread's join()... and how about reading up on such basics
before posting? There's plenty of free books and tutorials out
there...

There is nothing wrong with a such a question appearing in this newsgroup.
 
T

Thomas G. Marshall

Simon Andrews coughed up:
I'm writing a class which can include a long IO-bound routine and I'm
trying to show a progress bar during the loading of this data. I've
separated the IO code into a seaprate thread which puts up a progress
pane to show what it's doing. This bit all works.

Err....Consider breaking it up further. The IO part should not be the thing
throwing up the progress bar. Consider making an IO facility that takes a
listener for updates. Then have something else throw up a progressbar that
gets driven by the information coming through that listener.

The problem is that my class returns a big data structure. Initially
this is empty and it is loaded dynamically the first time it's asked
for (using the separate threaded code). Subsequent calls use the
pre-loaded data and return quickly without doing the IO again.

The problem is how to get the call to the thread to wait for it to
complete before passing back the data structure. The code I'm using
is shown below. This works, but doesn't allow the window produced by
ProgressWindow to update. If I remove the while (!done) code the
progess window updates OK (and the data is loaded), but this method
returns instantly with a null value.

How can I make this method wait nicely for ProgressWindow to complete
whilst still allowing GUI updates to happen?

Far too many ways to deal with this. Take a stab at very simple
Thread.join() experiments first. That is a method that is specifically
designed for waiting for a thread to "finish".

I've never particularly like the name of it.
 
S

Simon Andrews

Thomas said:
Simon Andrews coughed up:



Err....Consider breaking it up further. The IO part should not be the thing
throwing up the progress bar. Consider making an IO facility that takes a
listener for updates. Then have something else throw up a progressbar that
gets driven by the information coming through that listener.

I'd kind of tried that approach too, but ended up stuck in the same
problem a level higher. Something always seemed to be blocking on the
last call from the main GUI which causes the progress window to fail to
refresh.

Far too many ways to deal with this. Take a stab at very simple
Thread.join() experiments first. That is a method that is specifically
designed for waiting for a thread to "finish".

Tried that too (probably got the semantics wrong though). Again doing
the join caused the parent to sit in a wait state which seemed to block
the updates to the GUI.

I found a kind of kludgy way around this in the end which was to do a
setModal(true) on the progress window (which subclassed JDialog). This
caused the parent to wait (but seemingly in a nice way) until the
loading code had finished. The thread separation still allowed the IO
to separate from the progress window update. This got me the semantics
I was after, but I guess I still need to do some more experimenting with
theads.

Cheers for the help

Simon.
 
A

Andrea Desole

Simon said:
I'd kind of tried that approach too, but ended up stuck in the same
problem a level higher. Something always seemed to be blocking on the
last call from the main GUI which causes the progress window to fail to
refresh.

I would expect that to work. Can you post some sample code?
 
R

Rogan Dawes

Simon said:
I'm writing a class which can include a long IO-bound routine and I'm
trying to show a progress bar during the loading of this data. I've
separated the IO code into a seaprate thread which puts up a progress
pane to show what it's doing. This bit all works.

The problem is that my class returns a big data structure. Initially
this is empty and it is loaded dynamically the first time it's asked for
(using the separate threaded code). Subsequent calls use the pre-loaded
data and return quickly without doing the IO again.

The problem is how to get the call to the thread to wait for it to
complete before passing back the data structure. The code I'm using is
shown below. This works, but doesn't allow the window produced by
ProgressWindow to update. If I remove the while (!done) code the
progess window updates OK (and the data is loaded), but this method
returns instantly with a null value.

How can I make this method wait nicely for ProgressWindow to complete
whilst still allowing GUI updates to happen?

Cheers

Simon.

One really simple way might be to use a ProgressMonitorInputStream
wrapped around your real InputStream:

<http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/ProgressMonitorInputStream.html>

Alternatively, consider using a SwingWorker:

<http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html>

Starting your data load in the SwingWorker thread, using
SwingUtilities.invokeLater() to update your ProgressMonitor
(<http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/ProgressMonitor.html#setProgress(int)>)
during the operation, and close()ing the ProgressMonitor in the
finished() method of SwingWorker.

You probably want to look at
<http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html>

Regards,

Rogan
 
T

Thomas G. Marshall

Simon Andrews coughed up:
Thomas G. Marshall wrote:
....[rip]...
Far too many ways to deal with this. Take a stab at very simple
Thread.join() experiments first. That is a method that is
specifically designed for waiting for a thread to "finish".

Tried that too (probably got the semantics wrong though). Again doing
the join caused the parent to sit in a wait state which seemed to
block the updates to the GUI.

Take a close look at what thread you are in when you attempt things. You
might be surprised to findout that within many listeners, you are in a
thread that just cannot do what you expect regarding I/O and further GUI
calls.

Other than that, please PARE the thing down to the *barest* minimum to cause
the block you mention. Be prepared to receive endless crap from us if it is
not pared down enough ;)

....[rip]...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,832
Latest member
GlennSmall

Latest Threads

Top