how do SwingUtilities.invokeLater(runnable) and Swing Timer work?

1.5k views Asked by At

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?
2

There are 2 answers

5
Alexei Kaigorodov On BEST ANSWER
  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.

0
Kayaman On

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).