Java - threading Swing

snotnose

Ars Tribunus Militum
2,747
Subscriptor
I have a program perfect for threading. Except at the core of the critical loop I call a Swing method. So how do I best do this?

A) Surround the Swing.method() with locks. Sounds slow.
B) Come up with an Object that threads create and the Swing thread interprets, and queue them up. Sounds like a lot of work with lots of threading gotchas.
C) Just store things in an array and Swing.method() does them when the threads are all done. This loses half the benefit of threading.
D) Don't worry about it, the results could be mighty interesting. I think I'll do this just for fun :)

This is not just my first Java threads program, it's my first threads of any sort. I've got a lot of experience with multi-process programs, none with threads.
 
It's been many years since I've done this, but IIRC I used invokeAndWait and invokeLater for accessing Swing from other threads. See https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingUtilities.html

IIRC Swing and multi-threading really doesn't work, and without doing some kind of workaround like you mentioned or SwingUtilities like I mentioned you're pretty much guaranteed to crash.
 

Lt_Storm

Ars Praefectus
16,294
Subscriptor++
So, generally the rule with GUI libraries like Swing is that anything that updates the UI needs to happen on the UI thread. This is what the invoke methods do. Of course, this is slow, really slow. So, the best answer is to avoid updating the interface frequently. So, if possible, don't do it at the core of a working loop. If you must, do it every thousand or so iterations.
 

snotnose

Ars Tribunus Militum
2,747
Subscriptor
I'm writing a Mandelbrot program to learn OO via Java. Did some timing, best case setPoint is irrelevant, worst case it's 40% of my inner loop. Typical looks to be about 20%. I think I'll make a big array for the results and when done calculating run through the array plotting it.

FWIW, "best case" is when the point is in the set and I multiply/add 1000 times, "worst case" is when the point escapes in 1-2 loops. Typical has most of the points escaping within 100 or so iterations.
 

ShuggyCoUk

Ars Tribunus Angusticlavius
9,975
Subscriptor++
If you’re updating the UI inside a tight inner loop you’re doing it wrong basically.

Humans can’t resolve it that fast so it’s wasting time.
(On really old stuff following the raster line could be a thing, but then you didn’t have multi threading or anything like the speed you have now)

Batch it up in some way. Some sort of deferred rendering is used for this normally. You compute a batch of stuff (where the batch size is optimised, perhaps dynamically, to happen at reasonable rates to be picked up from the UI thread every so often.

Doing this an entire screen worth at a time is the basic concept of double buffering for example.

Have your inner loop update a buffer, have the UI thread poll that buffer. The smarts is only redrawing what you need to since the last one, which you can do with fancy low/no lock design, or just post messages to the UI thread every so often saying “X to Y is updated, please redraw”