On Sun, 05 Apr 2009 21:53:07 -0700, Knute Johnson
<nospam@rabbitbrush.frazmtn.com> wrote:
[...]
Do you think that a thread enqueueing(sp) an event on the EDT with
invokeLater() produces a happens before relationship with that thread
even though Thread.start() is not called? Could that same mechanism
work in calls to repaint()?
It has to.
I had to do some digging, because even though I suspect repaint() is
thread-safe, it's not very clear in the main JDK documentation
(actually, the main documentation doesn't mention it at all, even though
it elsewhere specifically says "any Swing method that isn't documented
as thread-safe, isn't". Even the article "Painting in AWT and Swing"
merely hints at it. It wasn't until I found the article "Threads and
Swing"
(http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html),
which I'm sure I've read before, but of course can't remember every
word, that I found a clear, direct statement to that effect.
Anyway, the up-shot is, since the RepaintManager is using invokeLater()
to cause the repainting to occur, there has to be a "happens-before"
relationship there, implicit in calling invokeLater(). Otherwise,
invokeLater() couldn't work reliably. So, if the thread that updates
the BufferedImage calls repaint() when it's done to indicate to the
component that uses the BufferedImage it's ready to be drawn, the update
to the BufferedImage must "happen before" the queuing to the EDT, which
in turn must "happen before" the code to actually redraw the component.
So, the update to the BufferedImage must "happen before" the redrawing
of the component.
Pete
That's what I think too but I can't prove it.