Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

repaint method and design question

7 views
Skip to first unread message

conrad

unread,
Jun 28, 2008, 8:58:37 PM6/28/08
to
I have two classes:
one for the GUI the other for various scanning methods
on a file system.

I'm experiencing an issue where, while scanning,
the main pane, if minimized and brought back up,
is blank. So I'm thinking I need to constantly
repaint while scanning?

In terms of design: should I be passing around
GUI objects(instance variables) from my GUI class
to my file system scanning class?

Or should I handle it differently?

--
conrad

Message has been deleted

Peter Duniho

unread,
Jun 28, 2008, 10:56:40 PM6/28/08
to
On Sat, 28 Jun 2008 17:58:37 -0700, conrad <con...@lawyer.com> wrote:

> I have two classes:
> one for the GUI the other for various scanning methods
> on a file system.
>
> I'm experiencing an issue where, while scanning,
> the main pane, if minimized and brought back up,
> is blank. So I'm thinking I need to constantly
> repaint while scanning?

Your code that is scanning is preventing the event dispatcher thread (EDT)
from dispatching events, because (I presume) you are scanning in response
to some user input and not returning from the user input handler (a
listener of some sort, probably an ActionListener, I also presume) until
the scanning is done.

If you don't want the GUI to freeze up while the scanning is being done,
then you'll need to run the scanning on a different thread, using
EventQueue.invokeLater() or EventQueue.invokeAndWait() to perform updates
to the components of your GUI (so that that code is executed on the EDT
where it belongs).

> In terms of design: should I be passing around
> GUI objects(instance variables) from my GUI class
> to my file system scanning class?

That's a somewhat different question. Ideally, I think your file scanning
class would not know about the GUI. It'd expose some sort of listener
interface that the GUI class can add a listener to in order to receive
updates on the progress of the scanning (for example, you might call the
listener method for each file, or each directory you scan, or you might
just have a "done" event that's called when the scan is complete). Then
the GUI class's handler method that's called for the event would handle
invoking the actual code on the EDT.

But you certainly could have the scanning class know about the GUI and
just update the GUI directly. Not the best model, since it ties the
classes together closely, but for quick and dirty stuff, sometimes that's
just fine.

Either way, you need to address the "blocking the EDT" issue if you want
the GUI to update while the scanning is going on. And neither approach
specifically addresses that issue.

Pete

Roedy Green

unread,
Jun 28, 2008, 11:03:34 PM6/28/08
to
On Sat, 28 Jun 2008 17:58:37 -0700 (PDT), conrad <con...@lawyer.com>
wrote, quoted or indirectly quoted someone who said :

>I'm experiencing an issue where, while scanning,
>the main pane, if minimized and brought back up,
>is blank. So I'm thinking I need to constantly
>repaint while scanning?

I don't know what you meant by "scanning" but if it is as all CPU
intensive or long lasting, you should do it on a separate thread, not
the EDT. See http://mindprod.com/jgloss/swingthreads.html
for details.
--

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Peter Duniho

unread,
Jun 28, 2008, 11:05:14 PM6/28/08
to
On Sat, 28 Jun 2008 19:56:40 -0700, Peter Duniho
<NpOeS...@nnowslpianmk.com> wrote:

> [...]


>> In terms of design: should I be passing around
>> GUI objects(instance variables) from my GUI class
>> to my file system scanning class?
>
> That's a somewhat different question. Ideally, I think your file
> scanning class would not know about the GUI. It'd expose some sort of
> listener interface that the GUI class can add a listener to in order to
> receive updates on the progress of the scanning (for example, you might
> call the listener method for each file, or each directory you scan, or
> you might just have a "done" event that's called when the scan is
> complete). Then the GUI class's handler method that's called for the
> event would handle invoking the actual code on the EDT.
>
> But you certainly could have the scanning class know about the GUI and
> just update the GUI directly. Not the best model, since it ties the
> classes together closely, but for quick and dirty stuff, sometimes
> that's just fine.

Sorry to follow up my own post. I should point out that there's a third
option, of course: the scanning class can still not know anything about
the GUI, but also not provide an asynchronous interface. In that case,
the GUI class would have its own thread implementation that calls the
scanning class and deals with invoking the results back to the EDT.

Pete

John B. Matthews

unread,
Jun 29, 2008, 1:02:10 PM6/29/08
to
In article <upud645jcih1b2gb1...@4ax.com>,
Roedy Green <see_w...@mindprod.com.invalid> wrote:

> On Sat, 28 Jun 2008 17:58:37 -0700 (PDT), conrad <con...@lawyer.com>
> wrote, quoted or indirectly quoted someone who said :
>
> >I'm experiencing an issue where, while scanning,
> >the main pane, if minimized and brought back up,
> >is blank. So I'm thinking I need to constantly
> >repaint while scanning?
>
> I don't know what you meant by "scanning" but if it is as all CPU
> intensive or long lasting, you should do it on a separate thread, not
> the EDT. See http://mindprod.com/jgloss/swingthreads.html
> for details.

Roedy's right. Here's the outline of a simple model that may guide your
re-factoring. It uses a javax.swing.Timer to notify the GUI of interim
results (not compiled):

class Scanner extends Observable implements ActionListener, Runnable {

private int interval = 1000 / 4; // 4 Hz
private Timer timer;
private Results results;

public Scanner() {
super();
timer = new Timer(interval, this);
}

public void run() {
timer.start()
// lengthy code that generates results
timer.stop();
setChanged();
notifyObservers(results);
}

public void actionPerformed(ActionEvent e) {
// interim progress
setChanged();
notifyObservers(results);
}
}

public class ScanView extends JPanel implements Observer {
...
public void update(Observable o, Object arg) {
Results results = (Results) arg;
// fill in GUI components with results
this.repaint();
}
}
...
Scanner scanner = new Scanner();
new Thread((Runnable) scanner).start();

--
John B. Matthews
trashgod at gmail dot com
home dot woh dot rr dot com slash jbmatthews

Peter Duniho

unread,
Jun 30, 2008, 12:46:00 AM6/30/08
to
On Sun, 29 Jun 2008 10:02:10 -0700, John B. Matthews <nos...@nospam.com>
wrote:

>> I don't know what you meant by "scanning" but if it is as all CPU
>> intensive or long lasting, you should do it on a separate thread, not
>> the EDT. See http://mindprod.com/jgloss/swingthreads.html
>> for details.
>
> Roedy's right. Here's the outline of a simple model that may guide your
> re-factoring. It uses a javax.swing.Timer to notify the GUI of interim
> results (not compiled):

Please correct me if I'm wrong, but I see nothing in the code you posted
that ensures that the observer notification is done on the EDT. The
documentation specifically says that there are basically no guarantees as
to how the observer's update() method is called, never mind that it's
always called on the EDT (in fact, the docs also say that subclasses of
the Observable class may "deliver notifications on separate threads").

Since the notification happens in response to the timer event, and since
that event happens on the EDT, as long as the base Observable class always
executes notifications on the same thread on which notifyObservers() is
called, you're safe. But the docs don't restrict the Observable class in
this way. I personally wouldn't depend on the current implementation to
never change, unless there was some specific Java documentation that
promises that the Observable class will never change in this respect.

As long as I'm replying, I'll also point out that your sample code
conveniently skips demonstrating any of the synchronization code that
would be required in order to successfully respond to the timer while the
other thread is busily working on the time-consuming operation. This code
could in fact be included, yes...but it would not be an insignificant
change. In fact, it's arguably "the hard part" of the whole sample.

Personally, I'd skip the timer altogether, and simply update the UI at
convenient intervals throughout processing based simply on progress (say,
every N files, where N is selected based on how long each file would take
to process). Then just use invokeAndWait() or invokeLater() directly from
the processing thread to call code that would update the GUI. This allows
the processing thread to package up the interesting data synchronously
without any actual explicit synchronization overhead, and send it off to
the GUI via the EDT, taking advantage of the EDT's own built-in
synchronization mechanisms.

Just my two cents. :)

Pete

John B. Matthews

unread,
Jun 30, 2008, 6:32:07 PM6/30/08
to
In article <op.udjou...@petes-computer.local>,
"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote:

> On Sun, 29 Jun 2008 10:02:10 -0700, John B. Matthews <nos...@nospam.com>
> wrote:
>
> >> I don't know what you meant by "scanning" but if it is as all CPU
> >> intensive or long lasting, you should do it on a separate thread, not
> >> the EDT. See http://mindprod.com/jgloss/swingthreads.html
> >> for details.
> >
> > Roedy's right. Here's the outline of a simple model that may guide your
> > re-factoring. It uses a javax.swing.Timer to notify the GUI of interim
> > results (not compiled):
>
> Please correct me if I'm wrong, but I see nothing in the code you posted
> that ensures that the observer notification is done on the EDT. The
> documentation specifically says that there are basically no guarantees as
> to how the observer's update() method is called, never mind that it's
> always called on the EDT (in fact, the docs also say that subclasses of
> the Observable class may "deliver notifications on separate threads").

I appreciate your critical analysis! This is an outline of an approach
I've used (successfully) several times for simulations in which a view
displays the interim results calculated by an asynchronously running
model. I'm sure I've overlooked a critical caveat or two:-)

My proposed Scanner implements Runnable, so it's a separate thread. I
recall reading the "separate threads" warning, but I understood the
warning to refer to notification order not being preserved across
threads. Timer(int, ActionListener) ensures that notification is done on
the EDT, but I'm not sure that is required. More importantly, the
Observer is running on the EDT, as it extends an AWT Component.

> Since the notification happens in response to the timer event, and since
> that event happens on the EDT, as long as the base Observable class always
> executes notifications on the same thread on which notifyObservers() is
> called, you're safe. But the docs don't restrict the Observable class in
> this way. I personally wouldn't depend on the current implementation to
> never change, unless there was some specific Java documentation that
> promises that the Observable class will never change in this respect.

The javax.swing.Timer I proposed runs on a separate thread; only it's
action handler executes on the EDT. One _could_ put drawing code in the
handler, but sending a notification instead keeps the model and view
separate. I thinka java.util.Timer would do as well.

> As long as I'm replying, I'll also point out that your sample code
> conveniently skips demonstrating any of the synchronization code that
> would be required in order to successfully respond to the timer while the
> other thread is busily working on the time-consuming operation. This code
> could in fact be included, yes...but it would not be an insignificant
> change. In fact, it's arguably "the hard part" of the whole sample.

Yes, a caveat is warranted: The data structure that the model is
updating must be consistent for a given instant of simulated time, or
the view must receive a consistent copy/snapshot. In the OP's case, it
wouldn't do to have the scanner updating the same TableModel used by the
view!

> Personally, I'd skip the timer altogether, and simply update the UI at
> convenient intervals throughout processing based simply on progress (say,
> every N files, where N is selected based on how long each file would take
> to process). Then just use invokeAndWait() or invokeLater() directly from
> the processing thread to call code that would update the GUI. This allows
> the processing thread to package up the interesting data synchronously
> without any actual explicit synchronization overhead, and send it off to
> the GUI via the EDT, taking advantage of the EDT's own built-in
> synchronization mechanisms.

This approach makes better sense than mine for the OP's file scanning
operation. Of course, the scanner thread still has to decide when it has
useful, self-consistent, interim results. My approach may be more suited
to watching a numerical simulation evolve, where there's no _a_priori_
way to know a preferred update point, other than "periodically".

> Just my two cents. :)

Worth much more! What, with compound interest and the price of copper,
etc. :-)

Peter Duniho

unread,
Jul 1, 2008, 4:11:28 AM7/1/08
to
On Mon, 30 Jun 2008 15:32:07 -0700, John B. Matthews <nos...@nospam.com>
wrote:

> [...]


> My proposed Scanner implements Runnable, so it's a separate thread. I
> recall reading the "separate threads" warning, but I understood the
> warning to refer to notification order not being preserved across
> threads.

Well, IMHO the docs are ambiguous. To me, the important part is that they
go out of their way to say that one should not rely on the notification
being done on a particular thread. The warning is in the context of
dealing with sub-classes of Observable, and so there _could_ be an
implication that as long as the sub-class doesn't change the default
implementation, the notification will be done on the same thread on which
notifyObservers() is called.

But that's an assumption, and as we all know, assumptions are not nearly
as valuable as things printed in black and white. :)

> Timer(int, ActionListener) ensures that notification is done on
> the EDT,

Now this is exactly what I'm talking about. The Swing Timer class does
ensure that the Action event itself happens on the EDT. However, there's
nothing about Timer that guarantees that when you call notifyObservers(),
the notification itself happens on the same thread on which that method
was called.

For example, one implementation could create a copy of the observer list
and then ship that off to yet another thread to process the list
asynchronously.

I don't even know for sure that the _current_ implementation keeps the
notification on the same thread as which notifyObservers() was called
(though I do agree it's likely, I haven't bothered to check it myself, and
the fact is it could be implementation-dependent), but it does seem to me
that the docs don't promise that even if it's true now, it always will be
true.

> but I'm not sure that is required. More importantly, the
> Observer is running on the EDT, as it extends an AWT Component.

It depends on what you mean by "is running on the EDT". It's true that
your Observer-implementing class is a Swing (not just AWT) component. But
that doesn't guarantee that code in that class is run on the EDT. In
fact, that's the whole issue: it _is_ a Swing component and so when you
execute Swing-dependent code in the class, you have to go out of your way
to ensure that happens on the EDT.

If that's what you meant, then yes...I agree. But if your statement was
intended to mean that because you've sub-classed JFrame, you're assured
that calls to your sub-class are always on the EDT, that would be wrong.

> The javax.swing.Timer I proposed runs on a separate thread; only it's
> action handler executes on the EDT. One _could_ put drawing code in the
> handler, but sending a notification instead keeps the model and view
> separate. I thinka java.util.Timer would do as well.

See above. I agree that the Timer Action event is raised on the EDT, but
that doesn't necessarily guarantee that the Observer's update() method is
called on the EDT. There's a missing link between your actionPerformed()
method being called, and the Observer's update() method being called that
involves ambiguously defined behavior on the part of the Java run-time.

>> As long as I'm replying, I'll also point out that your sample code
>> conveniently skips demonstrating any of the synchronization code that
>> would be required in order to successfully respond to the timer while
>> the
>> other thread is busily working on the time-consuming operation. This
>> code
>> could in fact be included, yes...but it would not be an insignificant
>> change. In fact, it's arguably "the hard part" of the whole sample.
>
> Yes, a caveat is warranted: The data structure that the model is
> updating must be consistent for a given instant of simulated time, or
> the view must receive a consistent copy/snapshot. In the OP's case, it
> wouldn't do to have the scanner updating the same TableModel used by the
> view!

Well, more specifically, since you know that the Timer Action event will
be raised on the EDT, and you also know that the scanning work is done on
a thread other than the EDT, you are assured that you need some kind of
synchronization mechanism. Even if this is as simple as having the
scanning thread making immutable copies of its progress at regular
intervals and assigned references to the data to a volatile variable,
_some_ sort of effort needs to be made to keep things synchronized.

>> Personally, I'd skip the timer altogether, and simply update the UI at
>> convenient intervals throughout processing based simply on progress
>> (say,
>> every N files, where N is selected based on how long each file would
>> take
>> to process). Then just use invokeAndWait() or invokeLater() directly
>> from
>> the processing thread to call code that would update the GUI. This
>> allows
>> the processing thread to package up the interesting data synchronously
>> without any actual explicit synchronization overhead, and send it off to
>> the GUI via the EDT, taking advantage of the EDT's own built-in
>> synchronization mechanisms.
>
> This approach makes better sense than mine for the OP's file scanning
> operation. Of course, the scanner thread still has to decide when it has
> useful, self-consistent, interim results. My approach may be more suited
> to watching a numerical simulation evolve, where there's no _a_priori_
> way to know a preferred update point, other than "periodically".

Agreed...to the extent that it might be difficult to determine what a
"preferred update point" is, a timer-based approach might work better.
I'm not sure that that applies to a numerical simulation, but that's only
because of the broadness of that genre of algorithms. Some numerical
simulations lend themselves just fine to predictable update points, others
might not.

Note, however, that the more likely that an algorithm is specifically in
need of a timer-based approach, the more complex the synchronization
mechanism will have to be (i.e. just copying immutable results to a
volatile variable won't do, since if you could do that, it'd imply that
you do in fact have predictable update points :) ).

>> Just my two cents. :)
>
> Worth much more! What, with compound interest and the price of copper,
> etc. :-)

Thanks. :)

Pete

John B. Matthews

unread,
Jul 1, 2008, 3:57:37 PM7/1/08
to
In article <op.udls1...@petes-computer.local>,
"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote:

> On Mon, 30 Jun 2008 15:32:07 -0700, John B. Matthews <nos...@nospam.com>
> wrote:
>
> > [...]
> > My proposed Scanner implements Runnable, so it's a separate thread. I
> > recall reading the "separate threads" warning, but I understood the
> > warning to refer to notification order not being preserved across
> > threads.
>
> Well, IMHO the docs are ambiguous. To me, the important part is that they
> go out of their way to say that one should not rely on the notification
> being done on a particular thread. The warning is in the context of
> dealing with sub-classes of Observable, and so there _could_ be an
> implication that as long as the sub-class doesn't change the default
> implementation, the notification will be done on the same thread on which
> notifyObservers() is called.

Yes, the subclass that implements Observable should behave correctly,
but I read the paragraph about notification order as a warning to
Observers that an Observable may change the order and thread.

> But that's an assumption, and as we all know, assumptions are not nearly
> as valuable as things printed in black and white. :)

Agreed!

> > Timer(int, ActionListener) ensures that notification is done on
> > the EDT,
>
> Now this is exactly what I'm talking about. The Swing Timer class
> does ensure that the Action event itself happens on the EDT.
> However, there's nothing about Timer that guarantees that when you
> call notifyObservers(), the notification itself happens on the same
> thread on which that method was called.
>
> For example, one implementation could create a copy of the observer
> list and then ship that off to yet another thread to process the
> list asynchronously.
>
> I don't even know for sure that the _current_ implementation keeps
> the notification on the same thread as which notifyObservers() was
> called (though I do agree it's likely, I haven't bothered to check
> it myself, and the fact is it could be implementation-dependent),
> but it does seem to me that the docs don't promise that even if it's
> true now, it always will be true.

I don't think it matters as long as the Observer respects the
order/thread warning above. In particular, my proposed Observer's
update(Observable, Object) method ends with repaint(). The hidden
assumption is that repaint() must be invoked from a JComponent, which
uses the RepaintManager to run from the EDT:

<http://java.sun.com/products/jfc/tsc/articles/painting/index.html#paint_
process>

> > but I'm not sure that is required. More importantly, the
> > Observer is running on the EDT, as it extends an AWT Component.
>
> It depends on what you mean by "is running on the EDT". It's true
> that your Observer-implementing class is a Swing (not just AWT)
> component. But that doesn't guarantee that code in that class is
> run on the EDT. In fact, that's the whole issue: it _is_ a Swing
> component and so when you execute Swing-dependent code in the class,
> you have to go out of your way to ensure that happens on the EDT.

Good point! I should have said JComponent.



> If that's what you meant, then yes...I agree. But if your statement was
> intended to mean that because you've sub-classed JFrame, you're assured
> that calls to your sub-class are always on the EDT, that would be wrong.

Yes, for JFrame. I proposed JPanel, which is a JComponent, but your
point is well taken.

> > The javax.swing.Timer I proposed runs on a separate thread; only
> > it's action handler executes on the EDT. One _could_ put drawing
> > code in the handler, but sending a notification instead keeps the
> > model and view separate. I thinka java.util.Timer would do as well.
>
> See above. I agree that the Timer Action event is raised on the EDT,
> but that doesn't necessarily guarantee that the Observer's update()
> method is called on the EDT. There's a missing link between your
> actionPerformed() method being called, and the Observer's update()
> method being called that involves ambiguously defined behavior on
> the part of the Java run-time.

As long as the Observer's update() repaints a lightweight container, I
don't think it matters if the notification doesn't come from the EDT.

> >> As long as I'm replying, I'll also point out that your sample code
> >> conveniently skips demonstrating any of the synchronization code
> >> that would be required in order to successfully respond to the
> >> timer while the other thread is busily working on the
> >> time-consuming operation. This code could in fact be included,
> >> yes...but it would not be an insignificant change. In fact, it's
> >> arguably "the hard part" of the whole sample.
> >
> > Yes, a caveat is warranted: The data structure that the model is
> > updating must be consistent for a given instant of simulated time,
> > or the view must receive a consistent copy/snapshot. In the OP's
> > case, it wouldn't do to have the scanner updating the same
> > TableModel used by the view!
>
> Well, more specifically, since you know that the Timer Action event
> will be raised on the EDT, and you also know that the scanning work
> is done on a thread other than the EDT, you are assured that you
> need some kind of synchronization mechanism. Even if this is as
> simple as having the scanning thread making immutable copies of its
> progress at regular intervals and assigned references to the data to
> a volatile variable, _some_ sort of effort needs to be made to keep
> things synchronized.

Agreed, although there are stochastic models where no synchronization at
all gives satisfactory results.

Don't similar synchronization problems attend to using the invoke*
utilities?

> >> Just my two cents. :)
> >
> > Worth much more! What, with compound interest and the price of copper,
> > etc. :-)
>
> Thanks. :)

--

Peter Duniho

unread,
Jul 1, 2008, 9:26:52 PM7/1/08
to
On Tue, 01 Jul 2008 12:57:37 -0700, John B. Matthews <nos...@nospam.com>
wrote:

> Yes, the subclass that implements Observable should behave correctly,

Define "correctly". The point of the statements in the documentation is
that the Observable class is not under any restriction regarding how it
deals with notification. That's my point. There's a whole range of what
can be considered "correct", including any variety of implementations that
don't allow you assume that the Observer's update() method is called on
the EDT.

> but I read the paragraph about notification order as a warning to


> Observers that an Observable may change the order and thread.

Yes, it may. And IMHO this can include the base Observable class.

> [...]


>> I don't even know for sure that the _current_ implementation keeps
>> the notification on the same thread as which notifyObservers() was
>> called (though I do agree it's likely, I haven't bothered to check
>> it myself, and the fact is it could be implementation-dependent),
>> but it does seem to me that the docs don't promise that even if it's
>> true now, it always will be true.
>
> I don't think it matters as long as the Observer respects the
> order/thread warning above. In particular, my proposed Observer's
> update(Observable, Object) method ends with repaint(). The hidden
> assumption is that repaint() must be invoked from a JComponent, which
> uses the RepaintManager to run from the EDT:
>
> <http://java.sun.com/products/jfc/tsc/articles/painting/index.html#paint_
> process>

Unfortunately, the documentation is not clear as to whether repaint() can
be called from a thread other than the EDT. Just because it queues a
Runnable to the EDT, that doesn't necessarily mean that it doesn't itself
need to be also called from the EDT.

More significantly, even if repaint() is legal to be called from any
thread, not just the EDT, in presenting a code example we should be VERY
explicit that we are relying on that specific behavior. Other
interactions with a component (AWT or Swing) could easily still be
required to be done on the EDT, even if the repaint() method need not be
(and to be clear: I remain unconvinced that the documentation promises
that to be true).

A naïve reader of the code example might incorrectly extrapolate from the
lack of special handling for repaint() that no special handling is needed
generally.

>> > but I'm not sure that is required. More importantly, the
>> > Observer is running on the EDT, as it extends an AWT Component.
>>
>> It depends on what you mean by "is running on the EDT". It's true
>> that your Observer-implementing class is a Swing (not just AWT)
>> component. But that doesn't guarantee that code in that class is
>> run on the EDT. In fact, that's the whole issue: it _is_ a Swing
>> component and so when you execute Swing-dependent code in the class,
>> you have to go out of your way to ensure that happens on the EDT.
>
> Good point! I should have said JComponent.

That's not what I am talking about. Whether you're talking Swing or EDT,
you need to make sure you are making calls to the component on the EDT.

>> If that's what you meant, then yes...I agree. But if your statement was
>> intended to mean that because you've sub-classed JFrame, you're assured
>> that calls to your sub-class are always on the EDT, that would be wrong.
>
> Yes, for JFrame. I proposed JPanel, which is a JComponent, but your
> point is well taken.

Again, for what I'm talking about, whether you are using JFrame or JPanel
doesn't matter. You still have the same "must be on EDT" requirement.

>> > The javax.swing.Timer I proposed runs on a separate thread; only
>> > it's action handler executes on the EDT. One _could_ put drawing
>> > code in the handler, but sending a notification instead keeps the
>> > model and view separate. I thinka java.util.Timer would do as well.
>>
>> See above. I agree that the Timer Action event is raised on the EDT,
>> but that doesn't necessarily guarantee that the Observer's update()
>> method is called on the EDT. There's a missing link between your
>> actionPerformed() method being called, and the Observer's update()
>> method being called that involves ambiguously defined behavior on
>> the part of the Java run-time.
>
> As long as the Observer's update() repaints a lightweight container, I
> don't think it matters if the notification doesn't come from the EDT.

Well, I haven't seen any documentation that promises that. It could be
true, but I have no reason at the moment to believe that. But again, the
repaint() method is a very specific method; there is no general promise
that when interacting with an AWT or Swing component from the Observer's
update() method, it doesn't matter if the notification doesn't come from
the EDT. In many other scenarios, it definitely would matter.

Even if we grant that repaint() has special rules (and again, I'm not
convinced we should), the more general rule still needs to be followed for
other kinds of calls to the component. Presumably, if you're updating the
GUI, you will in fact find such calls, and they will need to be executed
on the EDT.

> [...]


>> Note, however, that the more likely that an algorithm is specifically
>> in need of a timer-based approach, the more complex the
>> synchronization mechanism will have to be (i.e. just copying
>> immutable results to a volatile variable won't do, since if you
>> could do that, it'd imply that you do in fact have predictable
>> update points :) ).
>
> Don't similar synchronization problems attend to using the invoke*
> utilities?

I don't really know what you mean here. By design, invokeLater() and
invokeAndWait() address synchronization issues related specifically to
those methods.

The code being invoked does need to deal with synchronization, possibly.
But when I write code like this, typically the only data being used in the
invoked code is the bare minimum data required to update the GUI. In
particular, the extraction of the relevant information from my model has
already been done, on the same thread that's processing the model, and
copied to some specific place used by the invoked code (sometimes this is
as simple as a "final" local variable used in an anonymous class).

In this paradigm, because only one thread is ever actually using the model
itself (the processing thread for the model), no synchronization issues
exist with respect to the model, and the invoke*() methods automatically
deal with synchronization issues that may exist with respect to the
component itself.

As I said, I'm not sure I understand your question. But my first
impression of what you're asking leads me to answer "no, similar problems
do not exist".

Pete

Lew

unread,
Jul 1, 2008, 9:36:02 PM7/1/08
to
John B. Matthews wrote:
> I don't think it matters as long as the Observer respects the
> order/thread warning above. In particular, my proposed Observer's
> update(Observable, Object) method ends with repaint(). The hidden
> assumption is that repaint() must be invoked from a JComponent, which
> uses the RepaintManager to run from the EDT:

I see nothing in the Javadocs for JComponent#repaint() that indicates that the
method is thread safe.

But you showed us
> <http://java.sun.com/products/jfc/tsc/articles/painting/index.html#paint_process>

which explains that repaint() is thread safe. This worries me, as I had
thought the Javadocs to be normative.

> ... there are stochastic models where no synchronization at
> all gives satisfactory results.

How do variable values communicate across threads in that case?

Or by "stochastic" do you mean that it doesn't matter, because the results are
intended to be random?

I really do wonder how one handles the memory-model concerns in that
"stochastic models" scenario. Would you be so gracious as to explain?

--
Lew

Peter Duniho

unread,
Jul 1, 2008, 9:47:14 PM7/1/08
to
On Tue, 01 Jul 2008 18:36:02 -0700, Lew <l...@lewscanon.com> wrote:

> I see nothing in the Javadocs for JComponent#repaint() that indicates
> that the method is thread safe.
>
> But you showed us
>> <http://java.sun.com/products/jfc/tsc/articles/painting/index.html#paint_process>
>

> which explains that repaint() is thread safe. [...]

Where does it do that? And please distinguish between "thread safe" as in
"need not be called on the EDT" and "thread safe" as in "can be called
simultaneously from multiple threads".

I read through that page and was unable to find a clear statement to the
effect of either type of "thread safe". I'd appreciate it if you could
direct me to the portion of the page that you believes does so.

Thanks,
Pete

Lew

unread,
Jul 1, 2008, 10:02:17 PM7/1/08
to

You're absolutely right. It says that the repaint() schedules the painting to
happen on the EDT, not that the action is thread safe in general terms.

In the context of this conversation, that means that it should be thread-safe
enough for the EDT, especially under the assumptions stated by - actually, by
you yourself:


> The code being invoked does need to deal with synchronization, possibly.
> But when I write code like this, typically the only data being used in the
> invoked code is the bare minimum data required to update the GUI.
> In particular, the extraction of the relevant information from my model has
> already been done, on the same thread that's processing the model, and
> copied to some specific place used by the invoked code (sometimes this is
> as simple as a "final" local variable used in an anonymous class).

So the promise of the cited article that the repaint() will happen on the EDT
makes it, most of the time, thread-safe enough.

--
Lew

Peter Duniho

unread,
Jul 1, 2008, 10:56:35 PM7/1/08
to
On Tue, 01 Jul 2008 19:02:17 -0700, Lew <l...@lewscanon.com> wrote:

>> [...]


>> I read through that page and was unable to find a clear statement to
>> the effect of either type of "thread safe". I'd appreciate it if you
>> could direct me to the portion of the page that you believes does so.
>
> You're absolutely right. It says that the repaint() schedules the
> painting to happen on the EDT, not that the action is thread safe in
> general terms.

But the latter is the question at hand. We're not concerned with whether
the actual painting happens on the EDT. That can be taken as granted.
The question is whether calling repaint() itself must happen on the EDT.
I've seen nothing to suggest that it's not required to be, and the general
rule described to me is that _all_ calls to AWT or Swing methods _must_ be
done on the EDT.

The repaint() method is an AWT method (being part of the
java.awt.Component class), and absent clear documentation to the contrary,
that means that it _must_ itself be done on the EDT. The fact that its
results also happen on the EDT is inconsequential to the issue.

> In the context of this conversation, that means that it should be
> thread-safe enough for the EDT, especially under the assumptions stated
> by - actually, by you yourself:
>
>> The code being invoked does need to deal with synchronization,
>> possibly. But when I write code like this, typically the only data
>> being used in the invoked code is the bare minimum data required to
>> update the GUI. In particular, the extraction of the relevant
>> information from my model has already been done, on the same thread
>> that's processing the model, and copied to some specific place used by
>> the invoked code (sometimes this is as simple as a "final" local
>> variable used in an anonymous class).

I don't know what you mean. I agree that if you design the code in the
way I suggest, it's fine. But this part of the thread isn't about whether
the design I propose is safe. I never would have proposed that design had
I not felt it's safe. This part of the thread is about whether the other
design that was proposed is safe.

> So the promise of the cited article that the repaint() will happen on
> the EDT makes it, most of the time, thread-safe enough.

You statement that "the repaint() will happen on the EDT" is ambiguous.
To me, saying "the <method name here>() will happen on..." means that the
call to the method itself will happen as described (in this case, "...on
the EDT"). But that is definitely not true.

If you mean that the consequential painting that occurs _after_ the call
to repaint() happens will happen on the EDT, then yes...I agree with
that. But IMHO your statement is an awkward way of saying that, and in
any case such a statement doesn't provide any insight as to the safety of
calling repaint() itself on an arbitrary thread.

Pete

Lew

unread,
Jul 1, 2008, 11:27:26 PM7/1/08
to
Peter Duniho wrote:
> On Tue, 01 Jul 2008 19:02:17 -0700, Lew <l...@lewscanon.com> wrote:
>
>>> [...]
>>> I read through that page and was unable to find a clear statement to
>>> the effect of either type of "thread safe". I'd appreciate it if you
>>> could direct me to the portion of the page that you believes does so.
>>
>> You're absolutely right. It says that the repaint() schedules the
>> painting to happen on the EDT, not that the action is thread safe in
>> general terms.
>
> But the latter is the question at hand. We're not concerned with
> whether the actual painting happens on the EDT. That can be taken as
> granted. The question is whether calling repaint() itself must happen
> on the EDT. I've seen nothing to suggest that it's not required to be,
> and the general rule described to me is that _all_ calls to AWT or Swing
> methods _must_ be done on the EDT.

According to the document cited,
> JComponent.repaint() registers an asynchronous repaint request to the
> component's RepaintManager, which uses invokeLater() to queue a Runnable to
> later process the request on the event dispatching thread.

That seems pretty clear to me, that all GUI actions occur on the EDT. I don't
see how whether repaint() being called off the EDT will hurt that.

The ambiguity that you dislike doesn't bother me, although I see what you
mean. The important things that must be on the EDT are, according to the
article. The question of whether anything of repaint() other than that
happens on the EDT is immaterial.

Again, I see the distinction that you describe, but I don't think it matters
from a practical standpoint. It's pretty clear that the document at least
intends to show that JComponent#repaint() can safely be called from off the
EDT, at least for the implementation described.

To me, the problem isn't whether the document is clear - it seems sufficiently
clear from here. The problem is whether it's reliable, the fact that it's on
java.sun.com notwithstanding. My distrust of the article stems from the fact
that it is not presented as a normative standard - I don't get from it that
Java promises that repaint() is implemented in an EDT-safe manner, only that
the particular implementation actually does so.

I would like to know of any documentation that commits to JComponent#repaint()
being an EDT-safe method, by which I mean it can be called from off the EDT
without harm.

--
Lew

John B. Matthews

unread,
Jul 1, 2008, 11:30:07 PM7/1/08
to
In article <m_2dnQeHKv4bRvfV...@comcast.com>,
Lew <l...@lewscanon.com> wrote:

> John B. Matthews wrote:
> > I don't think it matters as long as the Observer respects the
> > order/thread warning above. In particular, my proposed Observer's
> > update(Observable, Object) method ends with repaint(). The hidden
> > assumption is that repaint() must be invoked from a JComponent, which
> > uses the RepaintManager to run from the EDT:
>
> I see nothing in the Javadocs for JComponent#repaint() that indicates
> that the method is thread safe.

Yes, the SDN article is referenced in Component, and perhaps elsewhere.

> But you showed us
> > <http://java.sun.com/products/jfc/tsc/articles/painting/index.html#
> > paint_process>
>
> which explains that repaint() is thread safe.

Only for JComponents: "JComponent.repaint() registers an asynchronous

repaint request to the component's RepaintManager, which uses
invokeLater() to queue a Runnable to later process the request on the
event dispatching thread."

> This worries me, as I had thought the Javadocs to be normative.

A linked article is less dispositive, I suppose, but not entirely
unreliable:-)

> > ... there are stochastic models where no synchronization at
> > all gives satisfactory results.
>
> How do variable values communicate across threads in that case?
>
> Or by "stochastic" do you mean that it doesn't matter, because the
> results are intended to be random?

Yes, the results evolve in apparent random order: many kinds of
fractals; diffusion limited aggregation, which has a fractal character;
any iteration over a set of lattice points in which you don't care that
some points are from iteration n-1 and some from iteration n.

> I really do wonder how one handles the memory-model concerns in that
> "stochastic models" scenario. Would you be so gracious as to explain?

My point was only that sometimes it doesn't matter if the model is
changing under you. When it matters, you have to synchronize access, of
course. Sorry if I seemed to be arguing to the contrary.

Oh, and I hope I am always gracious!

Lew

unread,
Jul 1, 2008, 11:39:44 PM7/1/08
to
Lew wrote:
> I would like to know of any documentation that commits to
> JComponent#repaint() being an EDT-safe method, by which I mean it can be
> called from off the EDT without harm.

Maybe I should trust
<http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html>
although its claim that one can construct the GUI off the EDT turns out not to
be true. It does claim that:

> There are a few exceptions to the rule that all code that might affect a
> realized Swing component must run in the event-dispatching thread:
> ...
> The following JComponent methods are safe to call from any thread: repaint(),
> revalidate(), and invalidate(). The repaint() and revalidate() methods queue
> requests for the event-dispatching thread to call paint() and validate(),
> respectively. The invalidate() method just marks a component and all of its
> direct ancestors as requiring validation.

I think that handles both our concerns, does it not?

That same article seems to draw the distinction between "thread-safe" and
"safe to call from any thread" that you brought to our attention.

--
Lew

Lew

unread,
Jul 1, 2008, 11:59:04 PM7/1/08
to
John B. Matthews wrote:
> Yes, the SDN article is referenced in Component, and perhaps elsewhere.

I finally figured that out, after spending some quality time with the Javadocs.

It doesn't help that some of that outrigger documentation has been superseded,
but the docs don't reflect the new knowledge.

>>> ... there are stochastic models where no synchronization at
>>> all gives satisfactory results.

Lew wrote:
>> How do variable values communicate across threads in that case?
>>
>> Or by "stochastic" do you mean that it doesn't matter, because the
>> results are intended to be random?

John:


> Yes, the results evolve in apparent random order: many kinds of
> fractals; diffusion limited aggregation, which has a fractal character;
> any iteration over a set of lattice points in which you don't care that
> some points are from iteration n-1 and some from iteration n.

But without synchronization, the display thread might only see iteration zero
forever.

>> I really do wonder how one handles the memory-model concerns in that
>> "stochastic models" scenario. Would you be so gracious as to explain?

> My point was only that sometimes it doesn't matter if the model is
> changing under you. When it matters, you have to synchronize access, of

But don't model changes by very necessity have to be communicated somewhere,
eventually? Absent synchronization, either via the 'synchronized' keyword or
via any of the several other mechanisms that Java provides, there is no
guarantee in the memory model that those changes would ever escape to another
thread that needs them.

And if another thread doesn't need them, then it's not a multithreaded scenario.

I'm not sure failing to communicate model state actually contributes to the
stochasticism.

> Sorry if I seemed to be arguing to the contrary.

You are not.

> Oh, and I hope I am always gracious!

You are so.

--
Lew

Peter Duniho

unread,
Jul 2, 2008, 12:34:57 AM7/2/08
to
On Tue, 01 Jul 2008 20:39:44 -0700, Lew <l...@lewscanon.com> wrote:

> Lew wrote:
>> I would like to know of any documentation that commits to
>> JComponent#repaint() being an EDT-safe method, by which I mean it can
>> be called from off the EDT without harm.
>
> Maybe I should trust
> <http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html>
> although its claim that one can construct the GUI off the EDT turns out
> not to be true. It does claim that:
>
>> There are a few exceptions to the rule that all code that might affect
>> a realized Swing component must run in the event-dispatching thread:
>> ... The following JComponent methods are safe to call from any thread:
>> repaint(), revalidate(), and invalidate(). The repaint() and
>> revalidate() methods queue requests for the event-dispatching thread to
>> call paint() and validate(), respectively. The invalidate() method just
>> marks a component and all of its direct ancestors as requiring
>> validation.
>
> I think that handles both our concerns, does it not?

Sort of.

First, I think your observation that it seems to claim something "known"
to be false ("that one can construct the GUI off the EDT") is pertinent.
That is, if one accepts that that's incorrect advice, then that calls into
question the rest of the article.

Second, a specification is where one would find implementation-independent
descriptions of how the run-time should behave. These articles are nice
but, as you might have noticed from previous discussions, I'm loathe to
accept them as the last word on what I can and cannot depend on the Java
run-time doing.

Third, in the very specific example, the repaint() method is the only
_explicit_ AWT/Swing method being called. However, you'll note the
comment reading "// fill in GUI components with results", as well as my
later comments pointing out that one is generally going to be actually
changing the state of the GUI components. In other words, while the code
sample posted has only the repaint() method, in truth there are always
going to be other methods that don't share repaint()'s flexibility with
respect to the EDT.

This third point is the most important. In particular, the primary point
in my original response was that the Observable class makes no guarantees
that the Observer.update() method will be called on the same thread on
which Observable.notifyObservers() is called. So the fact that the
Timer's Action event is raised on the EDT doesn't imply that the
subsequent Observer.update() calls are also done on the EDT thread.

So even though there is apparently no need for repaint() to be called from
the EDT, the other method calls that would likely be found in the
Observer.update() method _do_ need to be called from the EDT and there's
not any guarantee in the posted code that they would be.

> That same article seems to draw the distinction between "thread-safe"
> and "safe to call from any thread" that you brought to our attention.

Yes. In particular, while it says repaint() is "safe to call from any
thread", the docs don't describe repaint() as a "thread-safe" method. One
thing that concerns me in that respect is the possibility that the
run-time itself might wind up calling repaint() at the same time one is
trying to call it from another thread, never mind your own code that might
be running on the EDT.

So, sure...you are allowed to call repaint() from another thread than the
EDT. But since the method isn't "thread-safe", you had darn well better
be sure that no other thread has the opportunity at that moment to call
repaint(). This effectively means putting the EDT on hold somehow (one
way would be to call invokeLater() with some code that would signal that
it's being executed and then wait on some synchronization object until the
thread that wants to call repaint() has done so).

In other words, this discussion is only making me feel more confident that
it _really_ makes more sense to use the "invoke" methods to get data over
to the EDT for use there, rather than trying to solve all the various
cross-thread synchronization issues oneself.

Pete

John B. Matthews

unread,
Jul 2, 2008, 1:07:16 AM7/2/08
to
In article <op.udm4y...@petes-computer.local>,
"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote:

> On Tue, 01 Jul 2008 12:57:37 -0700, John B. Matthews <nos...@nospam.com>
> wrote:
>
> > Yes, the subclass that implements Observable should behave correctly,
>
> Define "correctly". The point of the statements in the documentation
> is that the Observable class is not under any restriction regarding
> how it deals with notification. That's my point. There's a whole
> range of what can be considered "correct", including any variety of
> implementations that don't allow you assume that the Observer's
> update() method is called on the EDT.

I think we agree on this for subclasses.

> > but I read the paragraph about notification order as a warning to
> > Observers that an Observable may change the order and thread.
>
> Yes, it may. And IMHO this can include the base Observable class.

I must demur: "The default implementation provided in the Observable
class will notify Observers in the order in which they registered
interest..." tells me that order is preserved if my subclass doesn't
change it. If I do change it, Observers must accept that.

The phrases "...this notification mechanism is has nothing to do with
threads..." and "Each observer has its update method called..." tell me
that my subclass will execute the update() method of a registered
Observer even if they're in different threads, and Observers have to
accept what that implies.

> > [...]
> >> I don't even know for sure that the _current_ implementation keeps
> >> the notification on the same thread as which notifyObservers()
> >> was called (though I do agree it's likely, I haven't bothered to
> >> check it myself, and the fact is it could be
> >> implementation-dependent), but it does seem to me that the docs
> >> don't promise that even if it's true now, it always will be true.
> >
> > I don't think it matters as long as the Observer respects the
> > order/thread warning above. In particular, my proposed Observer's
> > update(Observable, Object) method ends with repaint(). The hidden
> > assumption is that repaint() must be invoked from a JComponent,
> > which uses the RepaintManager to run from the EDT:
> >
> > <http://java.sun.com/products/jfc/tsc/articles/painting/index.html#p

> > aint_ process>


>
> Unfortunately, the documentation is not clear as to whether repaint()
> can be called from a thread other than the EDT. Just because it
> queues a Runnable to the EDT, that doesn't necessarily mean that it
> doesn't itself need to be also called from the EDT.

Well, the article claims "JComponent.repaint() registers an asynchronous

repaint request to the component's RepaintManager, which uses

invokeLater() to queue a Runnable," which is precisely the approach you
proposed earlier.

> More significantly, even if repaint() is legal to be called from any
> thread, not just the EDT, in presenting a code example we should be
> VERY explicit that we are relying on that specific behavior. Other
> interactions with a component (AWT or Swing) could easily still be
> required to be done on the EDT, even if the repaint() method need not
> be (and to be clear: I remain unconvinced that the documentation
> promises that to be true).
>
> A naïve reader of the code example might incorrectly extrapolate from
> the lack of special handling for repaint() that no special handling
> is needed generally.

I agree. The scheme relies on repainting JComponents, and then only if
the SDN article is dispositive. It's a hidden assumption that I should
document.

> >> > but I'm not sure that is required. More importantly, the
> >> > Observer is running on the EDT, as it extends an AWT Component.
> >>
> >> It depends on what you mean by "is running on the EDT". It's true
> >> that your Observer-implementing class is a Swing (not just AWT)
> >> component. But that doesn't guarantee that code in that class is
> >> run on the EDT. In fact, that's the whole issue: it _is_ a Swing
> >> component and so when you execute Swing-dependent code in the
> >> class, you have to go out of your way to ensure that happens on
> >> the EDT.
> >
> > Good point! I should have said JComponent.
>
> That's not what I am talking about. Whether you're talking Swing or
> EDT, you need to make sure you are making calls to the component on
> the EDT.

I agree. The Observer's update() method should defer drawing, but it can
get interim results and update component data models, e.g. a
BufferedImage or a TableModel. It then calls repaint() to schedule the
screen update on the EDT.

I welcome your skepticism, but the documentation for Component.repaint()
makes repeated reference to the SDN article, and the article mentions
calling paint() from the EDT as step one for both AWT and Swing
components.

> > [...]
> >> Note, however, that the more likely that an algorithm is
> >> specifically in need of a timer-based approach, the more complex
> >> the synchronization mechanism will have to be (i.e. just copying
> >> immutable results to a volatile variable won't do, since if you
> >> could do that, it'd imply that you do in fact have predictable
> >> update points :) ).
> >
> > Don't similar synchronization problems attend to using the invoke*
> > utilities?
>
> I don't really know what you mean here. By design, invokeLater() and
> invokeAndWait() address synchronization issues related specifically
> to those methods.

I see the run() method getting called from the EDT, but with no special
synchronization, other than being added to the end of the queue.

> The code being invoked does need to deal with synchronization,
> possibly. But when I write code like this, typically the only data
> being used in the invoked code is the bare minimum data required to
> update the GUI. In particular, the extraction of the relevant
> information from my model has already been done, on the same thread
> that's processing the model, and copied to some specific place used
> by the invoked code (sometimes this is as simple as a "final" local
> variable used in an anonymous class).
>
> In this paradigm, because only one thread is ever actually using the
> model itself (the processing thread for the model), no
> synchronization issues exist with respect to the model, and the
> invoke*() methods automatically deal with synchronization issues
> that may exist with respect to the component itself.

Is the model also running on the EDT?

> As I said, I'm not sure I understand your question. But my first
> impression of what you're asking leads me to answer "no, similar
> problems do not exist".

I appreciate your patience helping me vet the approach. It's immensely
helpful in understanding it's limitations.

Peter Duniho

unread,
Jul 2, 2008, 3:08:06 AM7/2/08
to
On Tue, 01 Jul 2008 22:07:16 -0700, John B. Matthews <nos...@nospam.com>
wrote:

> [...]


>> > but I read the paragraph about notification order as a warning to
>> > Observers that an Observable may change the order and thread.
>>
>> Yes, it may. And IMHO this can include the base Observable class.
>
> I must demur: "The default implementation provided in the Observable
> class will notify Observers in the order in which they registered
> interest..." tells me that order is preserved if my subclass doesn't
> change it. If I do change it, Observers must accept that.

Nothing I wrote has anything to do with the _order_ in which observers are
notified.

> The phrases "...this notification mechanism is has nothing to do with
> threads..." and "Each observer has its update method called..." tell me
> that my subclass will execute the update() method of a registered
> Observer even if they're in different threads, and Observers have to
> accept what that implies.

What you wrote supports my point. Yet, you seem to be including it with
the intent to refute my point.

I can only conclude that either you misunderstand my point, or you
misunderstand the implications of "will execute the update() method of a
registered Observer even if they're in different threads".

On a slight tangent: it's not really clear from the above quote that you
understand an important point about threading. Specifically, an _object_
is not on a specific thread. The _execution_ of some code is on a
specific thread. A given class can have code that is executed on
arbitrarily many threads. There is no connection between a given object
and a given thread, except whatever connection is part of the actual
explicit implementation.

If you're confused about this, that could explain some of the disconnect
here.

> [...]


>> Unfortunately, the documentation is not clear as to whether repaint()
>> can be called from a thread other than the EDT. Just because it
>> queues a Runnable to the EDT, that doesn't necessarily mean that it
>> doesn't itself need to be also called from the EDT.
>
> Well, the article claims "JComponent.repaint() registers an asynchronous
> repaint request to the component's RepaintManager, which uses
> invokeLater() to queue a Runnable," which is precisely the approach you
> proposed earlier.

No, it's not.

To be clear: Lew has helped by pointing out _some_ documentation (such as
it is) that explains that the repaint() method can be successfully called
from a thread other than the EDT thread. So we've got that point out of
the way.

But, the approach I proposed has nothing to do with whether the _painting_
of the control is done on the EDT or not (and in fact, I take as granted
that it is, whatever else the implementation may be, since that's a
requirement of AWT and Swing).

So, the fact that when you call repaint(), that ultimately queues a
Runnable to the event queue that will eventually do the actual repainting
of the controls has absolutely nothing to do with how data is synchronized
between the processing thread and the GUI (EDT) thread.

>> More significantly, even if repaint() is legal to be called from any
>> thread, not just the EDT, in presenting a code example we should be
>> VERY explicit that we are relying on that specific behavior. Other
>> interactions with a component (AWT or Swing) could easily still be
>> required to be done on the EDT, even if the repaint() method need not
>> be (and to be clear: I remain unconvinced that the documentation
>> promises that to be true).
>>

>> A naïve reader of the code example might incorrectly extrapolate from


>> the lack of special handling for repaint() that no special handling
>> is needed generally.
>
> I agree. The scheme relies on repainting JComponents, and then only if
> the SDN article is dispositive. It's a hidden assumption that I should
> document.

Well, more importantly, you gloss over the real work: actually taking the
model data and using it to update the GUI. The repaint() method itself
doesn't do anything except actually redraw the GUI. For that to be a
useful operation, you have to first _change_ the GUI so that when it
redraws, the state of the GUI is actually different, reflecting the
current state of processing.

So yes, while the lack of a guarantee that the update() method is called
on the EDT doesn't hurt us with respect to calling repaint() (sort
of...see * below), it certainly would if you actually meant to _do_
anything with the GUI that presents the current state of processing.

(*) Note my comments in my reply to Lew regarding the thread safety of
calling repaint(). The docs do explain that you can call repaint() from a
thread other than the EDT. But they also say that any method that's
thread-safe will specifically say so, and repaint() doesn't say so. This
means that while it's legal to call repaint() from a non-EDT thread, you
are still required to address synchronization yourself, since repaint()
isn't a thread-safe method.

In other words, you're really only safe calling repaint() in one respect.
There's another, arguably more important respect, in which calling it from
another thread without synchronization is _not_ safe.

> [...]


>> That's not what I am talking about. Whether you're talking Swing or
>> EDT, you need to make sure you are making calls to the component on
>> the EDT.
>
> I agree. The Observer's update() method should defer drawing,

It does, by virtue of the repaint() method deferring actual drawing.

> but it can
> get interim results and update component data models, e.g. a
> BufferedImage or a TableModel. It then calls repaint() to schedule the
> screen update on the EDT.

But those "component data models" need to be synchronized. If you are not
executing your code on the EDT, then they may be being used by code
running on the EDT at the same time you are modifying them. And that's on
top of the fact that Swing does not automatically handle cross-thread
updates to data models for GUI components.

For example (from
http://java.sun.com/javase/6/docs/api/javax/swing/package-summary.html#threading):

...if a TableModel is attached to a JTable, the TableModel
should only be modified on the event dispatching thread.
If you modify the model on a separate thread you run the
risk of exceptions and possible display corruption

Conversely, if you _are_ executing your code on the EDT, then the data
model from which you're getting your actual information (that is, the
processing thread's model data structure) is what needs to be synchronized.

The bottom line is that you have a processing thread that's generating
data, but you can only display data on the EDT, which is by definition
going to be a different thread from the processing thread. You _must_
address synchronization of those threads any time you want data to flow
from one thread to the other. And the only way to present the results of
the processing (interim results or otherwise) to the user is to have data
flow from one thread to the other.

On top of all this, the Observable class doesn't give us any assurance
that Observer implementers are going to be called on the same thread on
which Observable.notifyObservers() is called. So your Observer
implementer cannot make the assumption that it's update() method is called
on the EDT, even if you call notifyObservers() on the EDT.

And finally (to conclude this particular logical progression), since your
Observer implementation cannot make the assumption that its update()
method is called on the EDT, it must itself explicitly ensure that any
interaction it has with Swing is done on the EDT, except possibly for
things that are explicitly documented as not needing that (in this case,
that would be the repaint() method, but not any of the other things you
might do in order to update the GUI).

> [...]


>> Even if we grant that repaint() has special rules (and again, I'm not
>> convinced we should), the more general rule still needs to be followed
>> for
>> other kinds of calls to the component. Presumably, if you're updating
>> the
>> GUI, you will in fact find such calls, and they will need to be executed
>> on the EDT.
>
> I welcome your skepticism, but the documentation for Component.repaint()
> makes repeated reference to the SDN article, and the article mentions
> calling paint() from the EDT as step one for both AWT and Swing
> components.

As I noted above, I concede the point that repaint() itself may be called
from a thread other than the EDT. However, please note:

-- that doesn't help with any of the other methods that you'll need to
call in order to update the GUI, and
-- since repaint() isn't documented as being thread-safe, you still
have a synchronization issue even with that method

>> > [...]
>> >> Note, however, that the more likely that an algorithm is
>> >> specifically in need of a timer-based approach, the more complex
>> >> the synchronization mechanism will have to be (i.e. just copying
>> >> immutable results to a volatile variable won't do, since if you
>> >> could do that, it'd imply that you do in fact have predictable
>> >> update points :) ).
>> >
>> > Don't similar synchronization problems attend to using the invoke*
>> > utilities?
>>
>> I don't really know what you mean here. By design, invokeLater() and
>> invokeAndWait() address synchronization issues related specifically
>> to those methods.
>
> I see the run() method getting called from the EDT, but with no special
> synchronization, other than being added to the end of the queue.

You see which "run() method" getting called from the EDT? How _isn't_
making sure some code is executed on the same thread as some other code
not obviously synchronizing those two pieces of code?

>> The code being invoked does need to deal with synchronization,
>> possibly. But when I write code like this, typically the only data
>> being used in the invoked code is the bare minimum data required to
>> update the GUI. In particular, the extraction of the relevant
>> information from my model has already been done, on the same thread
>> that's processing the model, and copied to some specific place used
>> by the invoked code (sometimes this is as simple as a "final" local
>> variable used in an anonymous class).
>>
>> In this paradigm, because only one thread is ever actually using the
>> model itself (the processing thread for the model), no
>> synchronization issues exist with respect to the model, and the
>> invoke*() methods automatically deal with synchronization issues
>> that may exist with respect to the component itself.
>
> Is the model also running on the EDT?

No, not the model I'm referring to. As I said, "only one thread is ever
actually using the model itself (the processing thread for the model)".
Since by definition, the processing thread is not the EDT, obviously the
model is not "running on the EDT" (inasmuch as the model could be
"running" on any thread...I wouldn't describe it that way, but rather as
simply the _processing thread_ is what's "running", and it modifies the
model as it runs; that's a bit of a semantic nit-pick though).

Pete

Lew

unread,
Jul 2, 2008, 7:45:25 AM7/2/08
to
John B. Matthews wrote:
> The phrases "...this notification mechanism is has nothing to do with
> threads..." and "Each observer has its update method called..." tell me
> that my subclass will execute the update() method of a registered
> Observer even if they're in different threads, and Observers have to
> accept what that implies.

The determination of the thread in which an action occurs depends on the
caller, not the called. It really doesn't make sense to say that an object is
"in" a thread - only actions occur in a thread.

Between that and the dangling antecedent for "they", I'm not certain I
understand the sentence, but I think you are saying that the thread in which
an Observer's update() will occur is the thread in which the observed object
makes the call. That would be the case.

--
Lew

John B. Matthews

unread,
Jul 2, 2008, 2:02:04 PM7/2/08
to
In article <moSdneZCUdWVYPfV...@comcast.com>,
Lew <l...@lewscanon.com> wrote:

> John B. Matthews wrote:
> > Yes, the SDN article is referenced in Component, and perhaps elsewhere.
>
> I finally figured that out, after spending some quality time with the
> Javadocs.
>
> It doesn't help that some of that outrigger documentation has been
> superseded,
> but the docs don't reflect the new knowledge.
>
> >>> ... there are stochastic models where no synchronization at
> >>> all gives satisfactory results.
>
> Lew wrote:
> >> How do variable values communicate across threads in that case?
> >>
> >> Or by "stochastic" do you mean that it doesn't matter, because the
> >> results are intended to be random?
>
> John:
> > Yes, the results evolve in apparent random order: many kinds of
> > fractals; diffusion limited aggregation, which has a fractal character;
> > any iteration over a set of lattice points in which you don't care that
> > some points are from iteration n-1 and some from iteration n.
>
> But without synchronization, the display thread might only see
> iteration zero forever.

In practice I haven't seen this. The model, an Observable, executes the
view's update(Observable Object) method, and the view either asks the
model for data or receives it as a parameter. For some models, the data
may be no more than a reference to an array of primitive types, which
the model continues to update even as the view accesses it to compose,
for example, a BufferedImage.

> >> I really do wonder how one handles the memory-model concerns in
> >> that "stochastic models" scenario. Would you be so gracious as to
> >> explain?
>
> > My point was only that sometimes it doesn't matter if the model is
> > changing under you. When it matters, you have to synchronize
> > access, of
>
> But don't model changes by very necessity have to be communicated
> somewhere, eventually? Absent synchronization, either via the
> 'synchronized' keyword or via any of the several other mechanisms
> that Java provides, there is no guarantee in the memory model that
> those changes would ever escape to another thread that needs them.

I can see this for more complex, non-thread-safe data structures. I
imagine a Vector, which is synchronized, or one of the
Collections.synchronized[Collection|List|Map|etc.] would do as well.

> And if another thread doesn't need them, then it's not a
> multithreaded scenario.
>
> I'm not sure failing to communicate model state actually contributes
> to the stochasticism.

Yes, the model is intended to be stochastic, not factitious:-)

> > Sorry if I seemed to be arguing to the contrary.
>
> You are not.
>
> > Oh, and I hope I am always gracious!
>
> You are so.

--

John B. Matthews

unread,
Jul 2, 2008, 5:07:47 PM7/2/08
to
In article <op.udnkr...@petes-computer.local>,
"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote:

> On Tue, 01 Jul 2008 22:07:16 -0700, John B. Matthews <nos...@nospam.com>
> wrote:
>
> > [...]
> >> > but I read the paragraph about notification order as a warning
> >> > to Observers that an Observable may change the order and thread.
> >>
> >> Yes, it may. And IMHO this can include the base Observable class.
> >
> > I must demur: "The default implementation provided in the
> > Observable class will notify Observers in the order in which they
> > registered interest..." tells me that order is preserved if my
> > subclass doesn't change it. If I do change it, Observers must
> > accept that.
>
> Nothing I wrote has anything to do with the _order_ in which
> observers are notified.

Ah, I misunderstood. I thought you were saying that the base Observable
class might change the order, when the documentation says the opposite.
I understand that subclasses may do so.

> > The phrases "...this notification mechanism is has nothing to do
> > with threads..." and "Each observer has its update method
> > called..." tell me that my subclass will execute the update()
> > method of a registered Observer even if they're in different
> > threads, and Observers have to accept what that implies.
>
> What you wrote supports my point. Yet, you seem to be including it
> with the intent to refute my point.
>
> I can only conclude that either you misunderstand my point, or you
> misunderstand the implications of "will execute the update() method
> of a registered Observer even if they're in different threads".

Yes, I misunderstood your point.

> On a slight tangent: it's not really clear from the above quote that
> you understand an important point about threading. Specifically, an
> _object_ is not on a specific thread. The _execution_ of some code
> is on a specific thread. A given class can have code that is
> executed on arbitrarily many threads. There is no connection
> between a given object and a given thread, except whatever
> connection is part of the actual explicit implementation.
>
> If you're confused about this, that could explain some of the
> disconnect here.

Of course, I don't know what I don't know, but I think I understand:-)
Lew helpfully pointed out my ambiguous antecedent, so let me restate:

Starting a new thread for a Runnable [e.g. new Thread((Runnable)
scanner).start()] causes the Runnable's run() method to begin executing
on a new thread. Invoking notifyObservers() causes the registered
Observer's update() method to execute on that same thread, even though
other methods in the Observable may be executing on another thread. In
particular, an Observable that extends JPanel (or some other top-level
container) may have (at most) one method executing on the EDT.

I think this is the genesis of your welcomed criticism of my approach.

> > [...]
> >> Unfortunately, the documentation is not clear as to whether
> >> repaint() can be called from a thread other than the EDT. Just
> >> because it queues a Runnable to the EDT, that doesn't necessarily
> >> mean that it doesn't itself need to be also called from the EDT.
> >
> > Well, the article claims "JComponent.repaint() registers an
> > asynchronous repaint request to the component's RepaintManager,
> > which uses invokeLater() to queue a Runnable," which is precisely
> > the approach you proposed earlier.
>
> No, it's not.
>
> To be clear: Lew has helped by pointing out _some_ documentation
> (such as it is) that explains that the repaint() method can be
> successfully called from a thread other than the EDT thread. So
> we've got that point out of the way.
>
> But, the approach I proposed has nothing to do with whether the
> _painting_ of the control is done on the EDT or not (and in fact, I
> take as granted that it is, whatever else the implementation may be,
> since that's a requirement of AWT and Swing).
>
> So, the fact that when you call repaint(), that ultimately queues a
> Runnable to the event queue that will eventually do the actual
> repainting of the controls has absolutely nothing to do with how
> data is synchronized between the processing thread and the GUI (EDT)
> thread.

I agree.

Permit me to defer comment to that part of the thread.

These point are well taken, and thank you for pointing out the
TableModel caveat. I've been modifying a BufferedImage's
WriteableRaster, so any problems may have been more in-apparent than
impossible.

Yes, I confounded the model as a class with the model's run() method.

On reflection, I see the clear contract the invokeLater() and
invokeAndWait() methods offer with respect to the EDT, and my approach
may have too many limitations.

John B. Matthews

unread,
Jul 2, 2008, 8:58:14 PM7/2/08
to
In article <eq6dnRa8nvHL9_bV...@comcast.com>,
Lew <l...@lewscanon.com> wrote:

Yes. Thank you for pointing out the ambiguity. I tried to make myself
clearer in my response to Pete.

Peter Duniho

unread,
Jul 3, 2008, 12:08:55 AM7/3/08
to
On Wed, 02 Jul 2008 14:07:47 -0700, John B. Matthews <nos...@nospam.com>
wrote:

> [...]


>> On a slight tangent: it's not really clear from the above quote that
>> you understand an important point about threading. Specifically, an
>> _object_ is not on a specific thread. The _execution_ of some code
>> is on a specific thread. A given class can have code that is
>> executed on arbitrarily many threads. There is no connection
>> between a given object and a given thread, except whatever
>> connection is part of the actual explicit implementation.
>>
>> If you're confused about this, that could explain some of the
>> disconnect here.
>
> Of course, I don't know what I don't know, but I think I understand:-)
> Lew helpfully pointed out my ambiguous antecedent, so let me restate:
>
> Starting a new thread for a Runnable [e.g. new Thread((Runnable)
> scanner).start()] causes the Runnable's run() method to begin executing
> on a new thread. Invoking notifyObservers() causes the registered
> Observer's update() method to execute on that same thread, even though
> other methods in the Observable may be executing on another thread.

Well, that depends on how you call notifyObservers(). The code you posted
does _not_ actually do this though. It calls notifyObservers() from the
actionPerformed() method, which is called by the Timer class on the EDT,
not the thread on which the Observable's run() method was called.

At _best_, this will cause the registered Observer's update() method to be
executed on the EDT, but in any case certainly not on the thread on which
the Observable's run() method was called. At worst, the notifyObservers()
method itself might actually use yet another thread for the purpose of
calling the Observer's update() method (I'd be surprised in the Sun
implementation of the base Observable class did that, but you never really
know and the docs go to some length to warn that you cannot count on that
happening).

> In
> particular, an Observable that extends JPanel (or some other top-level
> container) may have (at most) one method executing on the EDT.

I suppose that depends on your definition of "executing". Personally, I'd
say that any method still in the call stack is "executing", and in that
sense, any class at all can have any number of methods executing on the
EDT.

> I think this is the genesis of your welcomed criticism of my approach.

If by that you mean that, since your restatement of your previous
statement is flawed, then so too is your proposed approach to the original
question, then yes...I suppose this could be that "genesis". :)

> [...]


> These point are well taken, and thank you for pointing out the
> TableModel caveat. I've been modifying a BufferedImage's
> WriteableRaster, so any problems may have been more in-apparent than
> impossible.

I suspect that you were just lucky to have chosen an implementation that
is unlikely to have run into problems with WriteableRaster.
BufferedImage/WriteableRaster don't have the same EDT-related limitations
that JTable, etc. would have. But they aren't thread-safe either.

In your case however, my impression is that you are simply updating the
BufferedImage periodically, and my guess is that your period is much
longer than it would take to display the image on-screen. In that
particular implementation, you pretty much guarantee that the EDT is done
with the BufferedImage by the time you get around to trying to change it
again, and you wouldn't normally cause the EDT to try to access it again
until after you've finished changing it.

You probably can, if you try, cause a subtle display bug by forcing a
redraw of the image at the exact moment that the processing thread is
updating the BufferedImage. But you'd have to have just the right timing
(this is typical of threading bugs...the vast majority of the time, things
work fine, but once in a blue moon you hit the timing just right, and
things fail...sometimes quite dramatically :) ). And even doing that, in
this particular case the error would probably be very subtle, depending on
how exactly you're updating the BufferedImage (if you're just adding new
things to the image, then at worst the image displayed would have a
partial update...if you clear the image and redraw it from scratch, then
you might have a more easily-noticed problem).

> [...]


> On reflection, I see the clear contract the invokeLater() and
> invokeAndWait() methods offer with respect to the EDT, and my approach
> may have too many limitations.

I guess that depends on your definition of "limitations". But personally,
I'd say the contrary is true: your approach has too few limitations. :)
In particular, using invokeLater/AndWait() is somewhat more limited. But
with that limitation comes a clearer, simpler way to move data from one
thread to another.

Your approach is actually more flexible, but it carries with it a heavy
burden to fully address all of the threading issues, which include both
the requirement to ensure that all methods (with few exceptions, like
repaint()) for a AWT/Swing component are called on the EDT, and the
requirement that you synchronize access to shared data structures between
any code running on the EDT and on your processing thread.

I would not expect there to typically be a need for the flexibility that
would justify the burden. Thus my suggestion to use the simpler, albeit
less flexible approach. :)

Pete

John B. Matthews

unread,
Jul 3, 2008, 7:25:36 AM7/3/08
to
In article <op.udo60...@petes-computer.local>,
"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote:

Worse! A serious flaw in the outline I proposed is that update() runs on
the EDT when sent by the Timer's actionPerformed() method, but the final
notification executes update() on the thread on which the

Observable's run() method was called.

> At _best_, this will cause the registered Observer's update() method
> to be executed on the EDT, but in any case certainly not on the
> thread on which the Observable's run() method was called. At worst,
> the notifyObservers() method itself might actually use yet another
> thread for the purpose of calling the Observer's update() method
> (I'd be surprised in the Sun implementation of the base Observable
> class did that, but you never really know and the docs go to some
> length to warn that you cannot count on that happening).

I am somewhat reassured that "... the action event handlers for Timers
execute on ... the event-dispatching thread," and that the Observable's
"... notification mechanism has nothing to do with threads..."

> > In particular, an Observable that extends JPanel (or some other top-

> > level container) may have (at most) one method executing on the EDT.


>
> I suppose that depends on your definition of "executing". Personally, I'd
> say that any method still in the call stack is "executing", and in that
> sense, any class at all can have any number of methods executing on the
> EDT.

Well, "executing" in the sense that drawing methods should execute only
on a single thread, the EDT.

> > I think this is the genesis of your welcomed criticism of my approach.
>
> If by that you mean that, since your restatement of your previous
> statement is flawed, then so too is your proposed approach to the original
> question, then yes...I suppose this could be that "genesis". :)

Permit me to amend my proposed outline, clarifying the need to
synchronize shared data and to execute update() on the EDT:

/**
* A model capable of running on a separate thread.
* A javax.swing.Timer is used for interim updates so that the
* actionPerformed() method executes on the event-dispatching thread.
*/
class Model extends Observable implements ActionListener, Runnable {



private int interval = 1000 / 4; // 4 Hz

private Timer timer; // javax.swing.Timer required
private Results results; // a synchronized Collection
private boolean done;

public Model() {


super();
timer = new Timer(interval, this);
}

public void run() {
done = false;
timer.start()
// generate results
done = true;
}

public void actionPerformed(ActionEvent e) {
if (done) timer.stop;
// notify Observer(s) of progress
setChanged();
notifyObservers(results);
}
}

/**
* A view capable of processing interim results from a model.
*/
public class View extends JPanel implements Observer {
View(Model model) {
...
model.addObserver(this);
}

/**
* Act on notifications from the model.
* This method relies on notifications being sent from the
* actionPerformed() method of a javax.swing.Timer in order
* to execute on the event-dispatching thread.
*/


public void update(Observable o, Object arg) {
Results results = (Results) arg;

// process results for display
this.repaint();
}
}
...
Model model = new Model();
new Thread((Runnable) model).start();

Yes. In previous tests, the shared data was simply a byte[][], so the
display was correct even in the worst case: a final update _not_
executing on the EDT, while paintComponent() was still executing _on_
the EDT.

> > [...]
> > On reflection, I see the clear contract the invokeLater() and
> > invokeAndWait() methods offer with respect to the EDT, and my approach
> > may have too many limitations.
>
> I guess that depends on your definition of "limitations". But personally,
> I'd say the contrary is true: your approach has too few limitations. :)
> In particular, using invokeLater/AndWait() is somewhat more limited. But
> with that limitation comes a clearer, simpler way to move data from one
> thread to another.
>
> Your approach is actually more flexible, but it carries with it a heavy
> burden to fully address all of the threading issues, which include both
> the requirement to ensure that all methods (with few exceptions, like
> repaint()) for a AWT/Swing component are called on the EDT, and the
> requirement that you synchronize access to shared data structures between
> any code running on the EDT and on your processing thread.

Yes, I am reluctant to abandon the approach completely; I like the
Observer/Observable pattern too well:-) Thank you, too for guiding me to
the (latent) bug described above.

> I would not expect there to typically be a need for the flexibility that
> would justify the burden. Thus my suggestion to use the simpler, albeit
> less flexible approach. :)

--

Peter Duniho

unread,
Jul 3, 2008, 2:15:24 PM7/3/08
to
On Thu, 03 Jul 2008 04:25:36 -0700, John B. Matthews <nos...@nospam.com>
wrote:

> [...]


>> > Starting a new thread for a Runnable [e.g. new Thread((Runnable)
>> > scanner).start()] causes the Runnable's run() method to begin
>> > executing on a new thread. Invoking notifyObservers() causes the
>> > registered Observer's update() method to execute on that same
>> > thread, even though other methods in the Observable may be
>> > executing on another thread.
>>
>> Well, that depends on how you call notifyObservers(). The code you
>> posted does _not_ actually do this though. It calls
>> notifyObservers() from the actionPerformed() method, which is called
>> by the Timer class on the EDT, not the thread on which the
>> Observable's run() method was called.

Please note, from the above: "...not the thread on which the Observable's
run() method was called"

> Worse! A serious flaw in the outline I proposed is that update() runs on


> the EDT when sent by the Timer's actionPerformed() method, but the final
> notification executes update() on the thread on which the
> Observable's run() method was called.

Ugh.

No, you are incorrect. Again, this seems to be a flaw in your
understanding about how threads work. It is _definitely_ not true that
"the final notificatione executes update() on the thread on which the
Observable's run() method was called". There is no way for Java to do
that, without you implementing it explicitly yourself.

I even reiterated the point here:

>> At _best_, this will cause the registered Observer's update() method
>> to be executed on the EDT, but in any case certainly not on the
>> thread on which the Observable's run() method was called.

Note in particular the last phrase in the sentence, starting with "but in
any case...".

>> At worst,
>> the notifyObservers() method itself might actually use yet another
>> thread for the purpose of calling the Observer's update() method
>> (I'd be surprised in the Sun implementation of the base Observable
>> class did that, but you never really know and the docs go to some
>> length to warn that you cannot count on that happening).
>
> I am somewhat reassured that "... the action event handlers for Timers
> execute on ... the event-dispatching thread," and that the Observable's
> "... notification mechanism has nothing to do with threads..."

I don't see how that reassures you.

>> > In particular, an Observable that extends JPanel (or some other top-
>> > level container) may have (at most) one method executing on the EDT.
>>
>> I suppose that depends on your definition of "executing". Personally,
>> I'd
>> say that any method still in the call stack is "executing", and in that
>> sense, any class at all can have any number of methods executing on the
>> EDT.
>
> Well, "executing" in the sense that drawing methods should execute only
> on a single thread, the EDT.

Again, you're not really being clear. Drawing methods may call other
drawing methods.

Either you are saying that the current instruction being executed can only
be in one method at a time (which is trivially true and uninteresting) or
you are saying that the EDT executes exactly one method per event queue
item (which is obviously false and could lead to some unfortunate mistakes
if it's believed).

It's not clear why the statement you made is relevant to the question at
hand anyway, but inasmuch as you believe it to be, that could be at least
partially responsible for your errors.

>> > I think this is the genesis of your welcomed criticism of my approach.
>>
>> If by that you mean that, since your restatement of your previous
>> statement is flawed, then so too is your proposed approach to the
>> original
>> question, then yes...I suppose this could be that "genesis". :)
>
> Permit me to amend my proposed outline, clarifying the need to
> synchronize shared data and to execute update() on the EDT:

The clarification is fine as far as it goes. But you still have a
synchronization bug and you are still relying on undocumented behavior.
In particular:

> public void run() {
> done = false;
> timer.start()
> // generate results
> done = true;
> }

The above method runs on thread A and modifies the data structure that
keeps the results of the processing.

> public void actionPerformed(ActionEvent e) {
> if (done) timer.stop;
> // notify Observer(s) of progress
> setChanged();
> notifyObservers(results);
> }

The above method runs on the EDT. In the current implementation of the
Java run-time I'm testing on, it winds up calling this method...

> /**
> * Act on notifications from the model.
> * This method relies on notifications being sent from the
> * actionPerformed() method of a javax.swing.Timer in order
> * to execute on the event-dispatching thread.
> */
> public void update(Observable o, Object arg) {
> Results results = (Results) arg;
> // process results for display
> this.repaint();
> }

...on the same thread (i.e. the EDT).

On the one hand, this is good for the purposes of applying whatever
changes have happened to whatever components are used to display the
results. On the other hand, you are relying on undocumented behavior, and
in addition you fail to synchronize access to the data structure that is
being modified on thread A.

The one positive aspect of the example is dependent on one of the negative
aspects, and fails to address the other negative aspects. I don't think
this is a good thing.

> [...]


>> Your approach is actually more flexible, but it carries with it a heavy
>> burden to fully address all of the threading issues, which include both
>> the requirement to ensure that all methods (with few exceptions, like
>> repaint()) for a AWT/Swing component are called on the EDT, and the
>> requirement that you synchronize access to shared data structures
>> between
>> any code running on the EDT and on your processing thread.
>
> Yes, I am reluctant to abandon the approach completely; I like the
> Observer/Observable pattern too well:-) Thank you, too for guiding me to
> the (latent) bug described above.

I'm afraid I can't take any credit yet, since so far you seem to be
believing there's a bug where there isn't, and failing to understand the
bugs where they are. :(

There's nothing fundamentally unfixable by your approach, but at the very
least, I think the difficulty in even _explaining_ the bugs is strongly
illustrative of the challenges involved in getting that approach to work
correctly. It's definitely not an implementation that someone
inexperienced with multi-threaded code should be trying to attempt.

Note also that it's not that there's anything wrong with using the
Observer/Observable pattern per se. You could almost as easily apply that
pattern to the approach I've suggested. The biggest problem is the lack
of any assurance that the Observer's update() method will be called on the
same thread that the Observable used to call notifyObservers(), but that's
addressable with a (potentially redundant) call to invokeLater/AndWait().

Pete

John B. Matthews

unread,
Jul 3, 2008, 11:43:56 PM7/3/08
to
In article <op.udqab...@petes-computer.local>,
"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote:

You've been extraordinarily patient, so I am reluctant to be
contradictory. In my original post, notifyObservers() is called each
time actionPerformed() is called by the Timer; and one final time in
run(), after the timer stops:

public void run() {
timer.start()
// lengthy code that generates results
timer.stop();
setChanged();
notifyObservers(results);
}

public void actionPerformed(ActionEvent e) {
// interim progress
setChanged();
notifyObservers(results);
}

The call stack shows a series of calls to update() via the EDT and a
final one in an anonymous thread on which the Observable's run() method
was called. It is definitely true. It was a bug. I fixed it in the
amended code below.

> >> At worst, the notifyObservers() method itself might actually use
> >> yet another thread for the purpose of calling the Observer's
> >> update() method (I'd be surprised in the Sun implementation of
> >> the base Observable class did that, but you never really know and
> >> the docs go to some length to warn that you cannot count on that
> >> happening).
> >
> > I am somewhat reassured that "... the action event handlers for
> > Timers execute on ... the event-dispatching thread," and that the
> > Observable's "... notification mechanism has nothing to do with
> > threads..."
>
> I don't see how that reassures you.

Observable states "that this notification mechanism has nothing to do
with threads..." The method notifyObservers() says, "Each observer has
its update method called..." Where does "yet another thread" come from?
Moreover, the warning specifically refers to subclasses of Observable
and the Observer's reliance on order. As long as my subclass of
Observable doesn't start another thread to issue notifications,
notifyObservers() will execute update() on the EDT, as arranged by Timer.

> >> > In particular, an Observable that extends JPanel (or some other

> >> > top-level container) may have (at most) one method executing on

> >> > the EDT.
> >>
> >> I suppose that depends on your definition of "executing".
> >> Personally, I'd say that any method still in the call stack is
> >> "executing", and in that sense, any class at all can have any
> >> number of methods executing on the EDT.
> >
> > Well, "executing" in the sense that drawing methods should execute only
> > on a single thread, the EDT.
>
> Again, you're not really being clear. Drawing methods may call other
> drawing methods.
>
> Either you are saying that the current instruction being executed can only
> be in one method at a time (which is trivially true and uninteresting) or
> you are saying that the EDT executes exactly one method per event queue
> item (which is obviously false and could lead to some unfortunate mistakes
> if it's believed).

I see your point that "executing" includes methods still in the call
stack. I understand that AWTEvents are dispatched from the EventQueue
sequentially and in the same order as they are put on the queue.

> It's not clear why the statement you made is relevant to the question at
> hand anyway, but inasmuch as you believe it to be, that could be at least
> partially responsible for your errors.
>
> >> > I think this is the genesis of your welcomed criticism of my approach.
> >>
> >> If by that you mean that, since your restatement of your previous
> >> statement is flawed, then so too is your proposed approach to the
> >> original
> >> question, then yes...I suppose this could be that "genesis". :)
> >
> > Permit me to amend my proposed outline, clarifying the need to
> > synchronize shared data and to execute update() on the EDT:
>
> The clarification is fine as far as it goes. But you still have a
> synchronization bug and you are still relying on undocumented behavior.

I understand the need for synchronization; I specified a synchronized
Collection, but the comment was elided. I believe the behavior is
documented, as described above.

I see the same result using the amended code.

> On the one hand, this is good for the purposes of applying whatever
> changes have happened to whatever components are used to display the
> results. On the other hand, you are relying on undocumented behavior, and
> in addition you fail to synchronize access to the data structure that is
> being modified on thread A.

I specified a synchronized Collection above, but this might be more
clear:

Results results = (Results) arg;

synchronized(results) {


// process results for display
}

> The one positive aspect of the example is dependent on one of the negative

> aspects, and fails to address the other negative aspects. I don't think
> this is a good thing.
>
> > [...]
> >> Your approach is actually more flexible, but it carries with it a
> >> heavy burden to fully address all of the threading issues, which
> >> include both the requirement to ensure that all methods (with few
> >> exceptions, like repaint()) for a AWT/Swing component are called
> >> on the EDT, and the requirement that you synchronize access to
> >> shared data structures between any code running on the EDT and on
> >> your processing thread.
> >
> > Yes, I am reluctant to abandon the approach completely; I like the
> > Observer/Observable pattern too well:-) Thank you, too for guiding me to
> > the (latent) bug described above.
>
> I'm afraid I can't take any credit yet, since so far you seem to be
> believing there's a bug where there isn't, and failing to understand the
> bugs where they are. :(

No, the spurious, final notification was calling update() on a thread
other than the EDT. That was a bug waiting to happen. You helped me look
at this critically. Thank you.

I think we agree that the contract for Timer specifies that action event
handlers for Timers execute on the EDT.

> There's nothing fundamentally unfixable by your approach, but at the very
> least, I think the difficulty in even _explaining_ the bugs is strongly
> illustrative of the challenges involved in getting that approach to work
> correctly. It's definitely not an implementation that someone
> inexperienced with multi-threaded code should be trying to attempt.

I'm no expert on multi-threading, but I sometimes get to track down bugs
in code written by people who are. :-)

> Note also that it's not that there's anything wrong with using the
> Observer/Observable pattern per se. You could almost as easily apply that
> pattern to the approach I've suggested. The biggest problem is the lack
> of any assurance that the Observer's update() method will be called on the
> same thread that the Observable used to call notifyObservers(), but that's
> addressable with a (potentially redundant) call to invokeLater/AndWait().

I believe my interpretation is reasonable, but I remain open.

Peter Duniho

unread,
Jul 4, 2008, 1:03:07 AM7/4/08
to
On Thu, 03 Jul 2008 20:43:56 -0700, John B. Matthews <nos...@nospam.com>
wrote:

>> > Worse! A serious flaw in the outline I proposed is that update() runs

>> on
>> > the EDT when sent by the Timer's actionPerformed() method, but the
>> final
>> > notification executes update() on the thread on which the
>> > Observable's run() method was called.
>>
>> Ugh.
>>
>> No, you are incorrect. Again, this seems to be a flaw in your
>> understanding about how threads work. It is _definitely_ not true that
>> "the final notificatione executes update() on the thread on which the
>> Observable's run() method was called". There is no way for Java to do
>> that, without you implementing it explicitly yourself.
>>

> [...]


> You've been extraordinarily patient, so I am reluctant to be
> contradictory. In my original post, notifyObservers() is called each
> time actionPerformed() is called by the Timer; and one final time in
> run(), after the timer stops:

Ah, I see. I failed to process the crucial word "final" (as in, "but the
final notification executes...") in your previous post. I thought you
were making the statement about _all_ notifications. (I'll blame it on
the fact that "final" wound up at the end of a line, and it's easy to miss
words at the end of a line :) ).

At least I was correct about there being "no way for Java to do that,
without implementing it explicitly yourself". You _did_ implement it
explicitly yourself.

Sorry for the confusion.

> [...]


> Observable states "that this notification mechanism has nothing to do
> with threads..." The method notifyObservers() says, "Each observer has
> its update method called..." Where does "yet another thread" come from?

It comes from either a change in the Java run-time implementation, or from
a sub-class that modifies the default behavior. The latter you already
understand. The former seems unlikely to me, but given that the
documentation doesn't provide a promise against the possibility, I'm
loathe to actually _depend_ on that.

But even the possibility of a different sub-class of Observable is an
important possibility. Sample code almost never gets run as-is. People
start there and then modify it. There's no way to guarantee that the
Observable class is the default one, or a sub-class that doesn't modify
the default threading behavior.

This is an issue that documentation, perhaps even to a degree that seems
excessive, can address successfully. But it does need to be
well-documented in the sample.

> [...]


>> > Permit me to amend my proposed outline, clarifying the need to
>> > synchronize shared data and to execute update() on the EDT:
>>
>> The clarification is fine as far as it goes. But you still have a
>> synchronization bug and you are still relying on undocumented behavior.
>
> I understand the need for synchronization; I specified a synchronized
> Collection, but the comment was elided. I believe the behavior is
> documented, as described above.

You did have a comment, but since your code doesn't actually demonstrate
the initialization and use of the Results, I'm afraid that a naïve reader
may gloss over or completely ignore the advice. IMHO it should be much
more explicit. Also consider that many scenarios don't even lend
themselves to having results of processing being stored in a collection.

It's nice to have collection classes that internalize synchronization, but
a person without that option may find themselves lost without more
explicit guidance as to how to synchronize across the threads (or may not
even realize the importance of the comment describing the "Results" class
as a synchronized collection).

> [...]


> I think we agree that the contract for Timer specifies that action event
> handlers for Timers execute on the EDT.

Yes, absolutely. For the Swing Timer class, this is essential.

Pete

John B. Matthews

unread,
Jul 4, 2008, 6:48:44 PM7/4/08
to
In article <op.udq4b...@petes-computer.local>,
"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote:

> On Thu, 03 Jul 2008 20:43:56 -0700, John B. Matthews <nos...@nospam.com>
> wrote:

> > [...]


> > In my original post, notifyObservers() is called each time
> > actionPerformed() is called by the Timer; and one final time in
> > run(), after the timer stops:
>
> Ah, I see. I failed to process the crucial word "final" (as in, "but the
> final notification executes...") in your previous post. I thought you
> were making the statement about _all_ notifications. (I'll blame it on
> the fact that "final" wound up at the end of a line, and it's easy to miss
> words at the end of a line :) ).
>
> At least I was correct about there being "no way for Java to do that,
> without implementing it explicitly yourself". You _did_ implement it
> explicitly yourself.
>
> Sorry for the confusion.

Not at all; I'd overlooked it for much longer! Plus, I always see
something new in the debugger and profiler:-)

> > [...]
> > Observable states "that this notification mechanism has nothing to do
> > with threads..." The method notifyObservers() says, "Each observer has
> > its update method called..." Where does "yet another thread" come from?
>
> It comes from either a change in the Java run-time implementation, or from
> a sub-class that modifies the default behavior. The latter you already
> understand. The former seems unlikely to me, but given that the
> documentation doesn't provide a promise against the possibility, I'm
> loathe to actually _depend_ on that.

Ah, I see the value in this distinction: the former may be less likely,
but it still deserves notice; the latter definitely requires a clear
prohibition against monkeying with the notification thread, as
established by Timer.

> But even the possibility of a different sub-class of Observable is an
> important possibility. Sample code almost never gets run as-is. People
> start there and then modify it. There's no way to guarantee that the
> Observable class is the default one, or a sub-class that doesn't modify
> the default threading behavior.
>
> This is an issue that documentation, perhaps even to a degree that seems
> excessive, can address successfully. But it does need to be
> well-documented in the sample.

I agree emphatically.

> > [...]


> > I understand the need for synchronization; I specified a

> > synchronized Collection [in] the comment[...]


>
> You did have a comment, but since your code doesn't actually demonstrate
> the initialization and use of the Results, I'm afraid that a naïve reader
> may gloss over or completely ignore the advice. IMHO it should be much
> more explicit. Also consider that many scenarios don't even lend
> themselves to having results of processing being stored in a collection.
>
> It's nice to have collection classes that internalize synchronization, but
> a person without that option may find themselves lost without more
> explicit guidance as to how to synchronize across the threads (or may not
> even realize the importance of the comment describing the "Results" class
> as a synchronized collection).

Yes, a single, easily-overlooked comment is insufficient. The shared
data may range from a single primitive type to an arbitrarily complex
data structure, and synchronization may be required for none, some or
all of the data. I've had excellent results where "none" was required,
but I want to experiment more with "some" and "all" for a time.

> > [...]

Lew

unread,
Jul 4, 2008, 6:53:23 PM7/4/08
to
John B. Matthews wrote:
> Yes, a single, easily-overlooked comment is insufficient. The shared
> data may range from a single primitive type to an arbitrarily complex
> data structure, and synchronization may be required for none, some or
> all of the data. I've had excellent results where "none" was required,
> but I want to experiment more with "some" and "all" for a time.

Any time you share data between threads, it is never the case that the amount
of synchronization required is "none". There are circumstances where it might
appear that the code is not broken for a while, but it's about as safe as
smoking cigarettes thinking you don't risk cancer just because it hasn't
happened yet.

Without some form of synchronization, there is absolutely no guarantee that
writes made by one thread will ever be visible for reads in another.

None.

--
Lew

John B. Matthews

unread,
Jul 5, 2008, 1:05:50 PM7/5/08
to
In article <Sa2dnZ_TefR-NPPV...@comcast.com>,
Lew <l...@lewscanon.com> wrote:

> John B. Matthews wrote:
> > Yes, a single, easily-overlooked comment is insufficient. The shared
> > data may range from a single primitive type to an arbitrarily complex
> > data structure, and synchronization may be required for none, some or
> > all of the data. I've had excellent results where "none" was required,
> > but I want to experiment more with "some" and "all" for a time.
>
> Any time you share data between threads, it is never the case that
> the amount of synchronization required is "none". There are
> circumstances where it might appear that the code is not broken for a
> while, but it's about as safe as smoking cigarettes thinking you
> don't risk cancer just because it hasn't happened yet.

No smoking! :-)

> Without some form of synchronization, there is absolutely no guarantee that
> writes made by one thread will ever be visible for reads in another.
>
> None.

Certainly a program must be correctly synchronized, but I'd naturally
like to use explicit synchronization no more than is required.

For example, elements of an int array are modified atomically and do not
need synchronization to ensure sequential consistency. While iterating,
a single writer and a single reader can race on at most one element; the
reader simply sees the previous value. Each full iteration is perceived
as atomic, although one element may be from iteration n-1. The Timer's
final notification ensures that the last complete writer iteration
happens before the start of the last reader iteration. The result is
correct with no explicit synchronization. In the absence of word
tearing, a similar case may be made for byte or short array. This is
what I meant by "none"; please correct me if I'm wrong.

In contrast, consider a model that reports interim progress as a
percentage of completion. If an Observer receives a new Number as the
actual parameter in update(), there is no shared data and no need for
synchronization at all.

I see the classes of java.util.concurrent.atomic extend the notion of
volatile, but they are new to me.

Of course, I already love the names. :-)

Lew

unread,
Jul 5, 2008, 2:20:08 PM7/5/08
to
John B. Matthews wrote:
> Certainly a program must be correctly synchronized, but I'd naturally
> like to use explicit synchronization no more than is required.

It is required *every* time threads share data.

> For example, elements of an int array are modified atomically and do not

Atomicity is not the problem. Visibility is.

> need synchronization to ensure sequential consistency. While iterating,
> a single writer and a single reader can race on at most one element; the
> reader simply sees the previous value. Each full iteration is perceived
> as atomic, although one element may be from iteration n-1. The Timer's

Wrong. Changes written by one thread may never be seen by another. The
reading thread might not see anything other than initial values, those from
just prior to iteration zero.

> final notification ensures that the last complete writer iteration
> happens before the start of the last reader iteration. The result is
> correct with no explicit synchronization. In the absence of word

Wrong. The happens-before relationship will not exist without synchronization.

> tearing, a similar case may be made for byte or short array. This is
> what I meant by "none"; please correct me if I'm wrong.

You are wrong. Only with synchronization is happens-before guaranteed.

> In contrast, consider a model that reports interim progress as a
> percentage of completion. If an Observer receives a new Number as the
> actual parameter in update(), there is no shared data and no need for
> synchronization at all.

As long as the thread is the same.

> I see the classes of java.util.concurrent.atomic extend the notion of
> volatile, but they are new to me.

Yes, they are a mere nearly four years old and introduced with a version now
in its End-of-Life processing.

The important thing is that they implement explicit synchronization internally.

Without synchronization, there is no happens-before established. Without
happens-before, changes may *never* propagate to a different thread.

--
Lew

John B. Matthews

unread,
Jul 5, 2008, 9:12:39 PM7/5/08
to
In article <hc-dnaqiEOfFJvLV...@comcast.com>,
Lew <l...@lewscanon.com> wrote:

> John B. Matthews wrote:
> > Certainly a program must be correctly synchronized, but I'd naturally
> > like to use explicit synchronization no more than is required.
>
> It is required *every* time threads share data.

[...]

> Atomicity is not the problem. Visibility is.

[...]

> Changes written by one thread may never be seen by another.

[...]

> The happens-before relationship will not exist without synchronization.

[...]

Ah, I think I'm back on the reservation. The memory model doesn't
_preclude_ visibility across threads, it just can't _guarantee_ it
without synchronization.

> > In contrast, consider a model that reports interim progress as a
> > percentage of completion. If an Observer receives a new Number as the
> > actual parameter in update(), there is no shared data and no need for
> > synchronization at all.
>
> As long as the thread is the same.
>
> > I see the classes of java.util.concurrent.atomic extend the notion of
> > volatile, but they are new to me.
>
> Yes, they are a mere nearly four years old and introduced with a version now
> in its End-of-Life processing.

Yes, I'm late to this corner of the party. :-)

> The important thing is that they implement explicit synchronization
> internally.
>
> Without synchronization, there is no happens-before established. Without
> happens-before, changes may *never* propagate to a different thread.

Thanks!

Lew

unread,
Jul 5, 2008, 11:01:44 PM7/5/08
to
Lew wrote:
>> Yes, they are a mere nearly four years old and introduced with a version now
>> in its End-of-Life processing.

John B. Matthews wrote:
> Yes, I'm late to this corner of the party. :-)

Do not misunderstand. I have yet to really use NIO, and that was out with 1.4!

But the chance to be sarcastic was just too tempting.

You demonstrated for everyone a beautiful way to respond to such, without
getting all whiny or upset. There are many who could benefit from your example.

--
Lew
Not humor, so no smileys. :-)

Lew

unread,
Jul 6, 2008, 1:45:05 AM7/6/08
to
Alvin B. Matthews wrote:
> Certainly a program must be correctly synchronized, but I'd naturally
> like to use explicit synchronization no more than is required.

It is subdued *few* time discounts share canoe.

> For example, elements of an int array are modified atomically and do not

Atomicity is not the domain. Visibility is.

> need synchronization to ensure sequential consistency. While iterating,
> a single writer and a single reader can race on at most one element; the
> reader simply sees the previous value. Each full iteration is perceived
> as atomic, although one element may be from iteration n-1. The Timer's

Wrong. Changes significant by one unction may already be seen by another. The
reading recommendation might not see anything other than initial values, those from


just prior to iteration zero.

> final notification ensures that the last complete writer iteration

> happens before the start of the last reader iteration. The result is
> correct with no explicit synchronization. In the absence of word

Wrong. The disturbs-before alliance will not flunk without messiness.

> tearing, a similar case may be made for byte or short array. This is
> what I meant by "none"; please correct me if I'm wrong.

You are urban. Only with voodoo is wallops-before stowed.

> In contrast, consider a model that reports interim progress as a
> percentage of completion. If an Observer receives a new Number as the
> actual parameter in update(), there is no shared data and no need for
> synchronization at all.

As inconceivable as the miracle is the same.

> I see the classes of java.util.concurrent.atomic extend the notion of
> volatile, but they are new to me.

Yes, they are a possible explicitly four stone ages frank and invalidated with an oxymoron this year
in its End-of-Life processing.

The insipid throat is that they pee jazzy warfare internally.

Without impersonation, there is no obsesses-before praised. Without
idolizes-before, changes may *therefore* arouse to a reprehensible objection.

--
Lew


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[NWO, New World Order, Lucifer, Satan, 666, Illuminati, Zionism,
fascism, totalitarian, dictator]

"The Cold War should no longer be the kind of obsessive
concern that it is. Neither side is going to attack the other
deliberately...If we could internationalize by using the U.N.
in conjunction with the Soviet Union, because we now no
longer have to fear, in most cases, a Soviet veto, then we
could begin to transform the shape of the world and might
get the U.N. back to doing something useful...Sooner or
later we are going to have to face restructuring our
institutions so that they are not confined merely to the
nation-states. Start first on a regional and ultimately you
could move to a world basis."

--- George Ball,
Former Under-secretary of State and CFR member
January 24, 1988 interview in the New York Times

Lew

unread,
Jul 6, 2008, 1:51:34 AM7/6/08
to
Lew wrote:
>> Yes, they are a mere nearly four years old and introduced with a version now
>> in its End-of-Life processing.

Frederick B. Matthews wrote:
> Yes, I'm late to this corner of the party. :-)

Do not misunderstand. I have yet to undoubtably bemuse NIO, and that was out with 1.4!

But the acquittal to be proportional was just too meditating.

You gorged for everyone a dreary way to obliterate to such, without
getting all bold or upset. There are plenty of who could benefit from your portion.

--
Lew
Not romance, so no smileys. :-)


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

"Because the picture on the newspaper.
It just seems so un-American to me,
the picture of the guy storming the house
with a scared little boy there.

I talked to my little brother, Jeb --
I haven't told this to many people.

But he's the governor of --
I shouldn't call him my little brother -- my brother, Jeb,
the great governor of Texas.

--- Adolph Bush,
Florida. The state of the Florida.
The NewsHour With Jim Lehrer, April 27, 2000

0 new messages