1

Case of study: I have a program with some model classes and some GUI classes in Swing where I use several threads in both of them which run an infinite loop with different sleep intervals for each runnable. two of model threads run a very critical job in which if the delay rises from 40ms to 60ms will not work correctly anymore so they are extremely critical.

But I have hundreds of components in GUI that must be updated in less than a second or more frequently. These components can't be updated with observer design pattern because they don't reflect only the changes in the model. they should calculate something such as remaining time.

Problem

  1. I think that it will not be efficient to use hundreds of Runnables invoked with SwingUtilities.invokeLater(runnable) to update all GUI components. Because the context switch will have an enormous side-effects. So I'm going to avoid it. Should I really avoid creating all those runnables or invokeLater() or swing timer doesn't run them as a thread and has an optimizing method even with all the Thread.sleep(500) among them ?
  2. For solving the above problem I decided to create an Interface SwingUpdatable with an update method. And create a SingleTonSwingUpdater which is run evry 500ms and run all the update methods of the classes registered with it. The observer design pattern made me to think about this idea. But I'm afraid that it will be an anti-pattern. And I'm not sure if it will reduce the flexiblity of the program.
  3. What if I use swing Timer. It surely can't understand that if the TimerTasks all should be run in 500ms time interval so there shouldn't be a new thread for them and it's enough to do a loop on the runnables and execute them one after another.
  4. Does Java have a built-in solution for this problem or is there a design pattern I can use or I should rely on my solution that at the first looks so dirty?
Johnny
  • 1,509
  • 5
  • 25
  • 38

2 Answers2

1

Well, if you have a long list of Runnables waiting to be executed, the time spent on EDT will grow and your timing may go off. But you should do at least a cursory test to see whether this will happen. Otherwise you'll be trying to solve a problem you don't have.

You could maybe try to coalesce events together to avoid doing unnecessary work. As a final remark, if your application is so time sensitive, you'll need to pay attention to the garbage collection as well (although this shouldn't be your first worry).

Kayaman
  • 72,141
  • 5
  • 83
  • 121
1
  1. SwingUtilities.invokeLater(runnable) adds runnable in a queue and then GUI thread executes them one at a time, so context switching is minimal. Avoid using Thread.sleep() in jobs running on GUI thread, use Swing timer instead.

  2. The proposed "solution" adds latency to the data visualization, and has no benefits. Be careful to add solutions to the problems you do not fully understand. Human intuition works badly inside computer.

  3. Swing's timer manages queue of timed jobs and passes them to the GUI thread when the delay expires. This is quite efficient approach.

  4. What problem are you talking about? Hundreds events per second is not so much, standard approaches should work. If they do not, probably they are misused.

Alexei Kaigorodov
  • 13,189
  • 1
  • 21
  • 38
  • I havn't already implemented this part of program completely but my intuition says that it can fail some day. because it's for industrial use on a single-core processor. There are some tackles which reading their positions and stopping them is very critical and if I fail to read the position and they pass the stop interval they will travel to the end of the line. while the program has hundreds of swing compound components which of them should calculate something about the state of a different object and update themselves. – Johnny Dec 12 '13 at 09:15
  • Btw, I understood now I think that I can use my solution only if I use swing timer inside my universal singletone swing updater. Still I'm not convinced that having hundreds of timers is a safe solution especially it's important to consider that every hour thousands of objects are created with these timers and the rest must be garbage collected – Johnny Dec 12 '13 at 09:18
  • Swing itself can generate hundreds of event objects per second (when a mouse pointer moves), so thousand objects per hour is a negligible number. Anyway, creating, drawing and reclaiming objects take indefinite time, so java+Swing are not supposed to be used in real time applications. Just make a prototype and make sure you have at least 10x reserve of processor time. Optimize your application to use less memory and CPU time, but only after measuring. Optimizing something which is not a bottleneck has no effect. – Alexei Kaigorodov Dec 12 '13 at 09:32
  • So my greatest mistake was using swing? Which UI could I have used instead if I wanted to write that application in Java? There are some applications like mine written with VB or C# that work very well on very older computers. Anyway the thing that makes me think threads go long is that "When I click a button to see only the details of only one product in the line it takes more than a second for the JFrame with all components to be created and shown(on my core i3 2.4GH processor). Now I have tens of products with on tenth of information that must be updated in the main window. – Johnny Dec 12 '13 at 09:43
  • this not necessarily a mistake. Human's ability to catch information from screen is limited anyway, and if you do not try to update the picture every millisecond, swing can serve perfectly. Find out exactly (by profiling) where that second is spend to create JFrame, probably the leak is out of Swing. – Alexei Kaigorodov Dec 12 '13 at 11:45