Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #28452 > unrolled thread
| Started by | Philipp Kraus <philipp.kraus@flashpixx.de> |
|---|---|
| First post | 2014-05-13 09:35 +0200 |
| Last post | 2014-05-13 10:46 -0700 |
| Articles | 7 — 4 participants |
Back to article view | Back to comp.lang.java.programmer
threadpool and ui paint Philipp Kraus <philipp.kraus@flashpixx.de> - 2014-05-13 09:35 +0200
Re: threadpool and ui paint Joerg Meier <joergmmeier@arcor.de> - 2014-05-13 11:26 +0200
Re: threadpool and ui paint markspace <markspace@nospam.nospam> - 2014-05-13 09:35 -0700
Re: threadpool and ui paint Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-05-13 08:10 -0400
Re: threadpool and ui paint markspace <markspace@nospam.nospam> - 2014-05-13 09:45 -0700
Re: threadpool and ui paint Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-05-13 13:22 -0400
Re: threadpool and ui paint markspace <markspace@nospam.nospam> - 2014-05-13 10:46 -0700
| From | Philipp Kraus <philipp.kraus@flashpixx.de> |
|---|---|
| Date | 2014-05-13 09:35 +0200 |
| Subject | threadpool and ui paint |
| Message-ID | <lkshvd$143g$1@ariadne.rz.tu-clausthal.de> |
Hello,
I have a lot of objects, which are calculated within a thread pool (by
a queue structure), so each object
as got an individual paint method for visualization. At the moment I
try to paint the objects within the threads
of the pool, but this creates exceptions.
Which is the correct way to do an UI painting? Each object needs an
individual paint structure, but all objects
can be painted after the thread has calculated the objects. In pseudo
code my structure shows:
class worker {
void run()
{
while (threadruns)
{
for all x = get object from queue
{
calculate x
push x back to the finish queue
- paint x -
}
- or here paint x -
thread await
for all y = ….
}
}
I'm a little bit confused with the Swing InvoceLater structure and in
which way I can imlemented this in my pool
Thanks
Phil
[toc] | [next] | [standalone]
| From | Joerg Meier <joergmmeier@arcor.de> |
|---|---|
| Date | 2014-05-13 11:26 +0200 |
| Message-ID | <1hwerxvmc8e0q.9djf9367s6xd$.dlg@40tude.net> |
| In reply to | #28452 |
On Tue, 13 May 2014 09:35:09 +0200, Philipp Kraus wrote:
> class worker {
> void run()
> {
>
> while (threadruns)
> {
> for all x = get object from queue
> {
> calculate x
> push x back to the finish queue
SwingUtilities.invokeLater(new Runnable() {
public void run() {
swingJLabelOrWhatever.setText(x);
}
});
> }
> - or here paint x -
>
> thread await
>
> for all y = ….
> }
>
> }
You need to surround all access to Swing components that way.
Liebe Gruesse,
Joerg
--
Ich lese meine Emails nicht, replies to Email bleiben also leider
ungelesen.
[toc] | [prev] | [next] | [standalone]
| From | markspace <markspace@nospam.nospam> |
|---|---|
| Date | 2014-05-13 09:35 -0700 |
| Message-ID | <lkthl3$h9u$1@dont-email.me> |
| In reply to | #28453 |
On 5/13/2014 2:26 AM, Joerg Meier wrote:
> On Tue, 13 May 2014 09:35:09 +0200, Philipp Kraus wrote:
>
>> class worker {
>> void run()
>> {
>>
>> while (threadruns)
>> {
>> for all x = get object from queue
>> {
>> calculate x
>> push x back to the finish queue
> SwingUtilities.invokeLater(new Runnable() {
> public void run() {
> swingJLabelOrWhatever.setText(x);
> }
> });
>> }
However, this is broken if 'x' is mutable. You can't mutate (change)
objects that are being accessed by more than one thread. You'll need to
synchronize 'x', and that can be a lot of hassle. The currency
tutorials barely scratch the surface.
I'm going to go out on a limb here and say M. Kraus isn't going to be
able to do that reliably, based on what we've seen from his posts.
I think M. Kraus is going to need to read the language spec, and get a
book called "Java Concurrency in Practice" by Brian Goetz. After
researching those two thoroughly he might be able to design something
workable.
http://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html
http://jcip.net.s3-website-us-east-1.amazonaws.com/
>> - or here paint x -
>>
>> thread await
>>
>> for all y = ….
>> }
>>
>> }
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2014-05-13 08:10 -0400 |
| Message-ID | <lkt242$qea$1@dont-email.me> |
| In reply to | #28452 |
On 5/13/2014 3:35 AM, Philipp Kraus wrote:
> Hello,
>
> I have a lot of objects, which are calculated within a thread pool (by a
> queue structure), so each object
> as got an individual paint method for visualization. At the moment I try
> to paint the objects within the threads
> of the pool, but this creates exceptions.
Yeah. Nearly everything that's done to or with a UI component must
take place on the Event Dispatching Thread, or EDT. If you manipulate
UI components from other threads, bad things are likely to happen. See
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html
for an explanation and examples.
> Which is the correct way to do an UI painting? Each object needs an
> individual paint structure, but all objects
> can be painted after the thread has calculated the objects. In pseudo
> code my structure shows:
>
> class worker {
> void run()
> {
>
> while (threadruns)
> {
> for all x = get object from queue
> {
> calculate x
> push x back to the finish queue
> - paint x -
> }
> - or here paint x -
>
> thread await
>
> for all y = ….
> }
>
> }
>
> I'm a little bit confused with the Swing InvoceLater structure and in
> which way I can imlemented this in my pool
Your outline is all right, so long as you make sure "paint x"
happens on the EDT. That's what SwingUtilities.invokeLater() does:
You construct a Runnable that does the painting or whatever else is
desired, and you give that Runnable to invokeLater(). You can do
this on any thread you like, but when the Runnable actually runs it
will be on the EDT. So, "paint x" looks something like
final Thing x = ...;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
x.updateTheDisplay();
}
});
If you want to wait until all the calculating is finished
before updating the display, it might go like
final Collection<Thing> finished = ...;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
for (Thing x : finished) {
x.updateTheDisplay();
}
}
});
(By the way, Java 8 introduces a more compact notation for this sort
of thing -- but that's another story, and the old way still works.)
Finally, you'll do yourself a favor if you divide the Thing into
two pieces: A "model" that owns the data and is responsible for the
computations that modify it, and a "view" that listens for notices
that the model has changed. This may seem at first to be a rather
pointless division of labor, but trust me: It pays off. See
http://docs.oracle.com/javase/tutorial/uiswing/components/model.html
for an explanation of this separation.
--
Eric Sosman
esosman@comcast-dot-net.invalid
[toc] | [prev] | [next] | [standalone]
| From | markspace <markspace@nospam.nospam> |
|---|---|
| Date | 2014-05-13 09:45 -0700 |
| Message-ID | <lkti7l$lhu$1@dont-email.me> |
| In reply to | #28454 |
This is broken if Thing or Collection is modifiable.
On 5/13/2014 5:10 AM, Eric Sosman wrote:
> final Collection<Thing> finished = ...;
> SwingUtilities.invokeLater(new Runnable() {
> @Override
> public void run() {
> for (Thing x : finished) {
> x.updateTheDisplay();
> }
> }
> });
The following would work, if you can guarantee that no Thing are being
changed while the invokeLater is running. Maybe use invokeNow instead
to make the update on the EDT synchronous.
final Collection<Thing> finished =
Collections.synchronizedCollection( new Collection() );
try { SwingUtilities.invokeNow(new Runnable() {
@Override
public void run() {
for (Thing x : finished) {
x.updateTheDisplay();
}
}
});
} catch( Exception ex ) {}
However if you have another thread besides these two that is updating
Thing asynchronously then this fails. You must also synchronize the
Thing object itself in that case.
Without a thorough understanding of threading and the Java memory model
copying by rote is fraught with error. One shouldn't be doing this sort
of thing unless one is an expert, or you're just plain going to make
broken code.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2014-05-13 13:22 -0400 |
| Message-ID | <lktkc1$6eh$1@dont-email.me> |
| In reply to | #28456 |
On 5/13/2014 12:45 PM, markspace wrote:
>
> This is broken if Thing or Collection is modifiable.
>
> On 5/13/2014 5:10 AM, Eric Sosman wrote:
>
>> final Collection<Thing> finished = ...;
>> SwingUtilities.invokeLater(new Runnable() {
>> @Override
>> public void run() {
>> for (Thing x : finished) {
>> x.updateTheDisplay();
>> }
>> }
>> });
>
>
> The following would work, if you can guarantee that no Thing are being
> changed while the invokeLater is running. Maybe use invokeNow instead
> to make the update on the EDT synchronous.
I think you mean SwingUtilities.invokeAndWait(). But yes: If the
Thing or the collection of Things is being changed while other parts
of the program are trying to capture "the" state of affairs, there'll
be nothing but trouble.
> final Collection<Thing> finished =
> Collections.synchronizedCollection( new Collection() );
> try { SwingUtilities.invokeNow(new Runnable() {
> @Override
> public void run() {
> for (Thing x : finished) {
> x.updateTheDisplay();
> }
> }
> });
> } catch( Exception ex ) {}
>
> However if you have another thread besides these two that is updating
> Thing asynchronously then this fails. You must also synchronize the
> Thing object itself in that case.
I don't think using synchronizedCollection() helps here. It will
ensure that individual actions on the collection are atomic, but will
not atomize (?!) sequences of actions. In particular, you can still
get a ConcurrentModificationException.
> Without a thorough understanding of threading and the Java memory model
> copying by rote is fraught with error. One shouldn't be doing this sort
> of thing unless one is an expert, or you're just plain going to make
> broken code.
This is yet another motivation for dividing the Thing into a model
and a view thereof: It becomes easier to ensure that multiple viewers
always see the Thing in a consistent state, even if that state is
mutable and mutating.
--
Eric Sosman
esosman@comcast-dot-net.invalid
[toc] | [prev] | [next] | [standalone]
| From | markspace <markspace@nospam.nospam> |
|---|---|
| Date | 2014-05-13 10:46 -0700 |
| Message-ID | <lktlp3$giu$1@dont-email.me> |
| In reply to | #28457 |
On 5/13/2014 10:22 AM, Eric Sosman wrote: > I don't think using synchronizedCollection() helps here. It will > ensure that individual actions on the collection are atomic, but will > not atomize (?!) sequences of actions. In particular, you can still > get a ConcurrentModificationException. Yes, if the collection is modified as the EDT is attempting to read it, that'll happen. I'm not sure that MVC will solve all of these issues, but a better architecture will definitely help decompose the problem(s) into easier pieces. I don't really like the way M. Kraus has designed his threading code at all.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web