Re: Graphics - how to show partial progress.
Lew wrote:
rossum wrote:
[snip code]
Daniel Pitts wrote:
Still got problems. you can't access a buffered images graphics from a
different thread without synchronization. You might be better off
queuing up *blocks* of calculations into a ConcurrentQueue, and then
during a repaint, use queue.poll, and build out your BufferedImage at
that time.
I'll bet he thought making the buffered image 'volatile' would do the
trick, and indeed, it would do part of it. I still have enough trouble
reasoning about concurrency to be unsure of the pitfalls of that
approach, though.
I know that it is indeed *not* enough... The threads are effectively
synchronized on the read/write to that reference, but not necessarily on
the internals. If there is a read to that reference, before a method
execution), then that method execution might still appear to complete
out-of-order compared to another method. Also, the fact that you grab a
graphics object that affects data read from a different thread, but
there is *no* synchronization, is a dangerous (i.e. broken) operation.
Don't forget to call Graphics2D.dispose() when you're done with the
graphics object you created.
Isn't it dangerous to call repaint() from off the EDT?
repaint actually creates an event on the EDT. it is safe to call from
any thread.
It also makes me nervous to see a thread kicked off from the GraphPanel
constructor, but I don't see any egregious actual danger from it yet.
Just that queasy feeling ...
A thread can be started anywhere, but should *not* have any reference to
the "this" pointer of the object that is being constructed. So, in this
case, you are correct.
As a matter of fact, you should never allow the "this" pointer to escape
the constructor. For example, while in the constructor never pass the
"this" pointer as a listener to some other object (MouseListener,
etc...). Feel free to add an "initialize" method, and have that stuff
done there. It might make sense to make your constructor private, and
use a factory method that uses new, and then calls the init method.
--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>