Friday, July 30, 2021

InvokeLater and InvokeAndWait in Java Swing (an example tutorial)

Everyone who is doing programming in java swing has to come across invokeAndWait and invokeLater provided by SwingUtilites. In this java swing tutorial, we will learn about both invokeLater() and invokeAndwait() method. In the first part, we will mostly focus on invokeLater and will find answers to questions like What is invokeLater, how to use invokelater in java swing, an example of invokelater in swing, etc while in the second part of this invokeLater tutorial we will learn more about invokeAndWait method in java swing and will learn Why we need InvokeAndWait, how to use InvokeAndWait method in java Swing and differences between invokelater and invokeAndWait.

Finally, we will see a code example of both invokeLater and invokeAndWait in Swing and will be able to decide when to use invokeLater and when to use invokeAndWait while doing Swing programming.  We will also see famous Swing interview questions "difference between invokeLater and invokeAndWait" at the end of the article.



Why do we need the InvokeLater method in Swing?

invokeAndWait invokeLater and SwingUtilities in javaBefore using invokelater or going deep about invokelater lets see why do we need this method in swing utility class? As we all know java swing is not threadsafe, you can not update swing components like JButton, JLable, JTable or JTree from any thread, they all need to be updated from just one thread and we call it Event Dispatcher thread or EDT in short.

 Event Dispatcher thread is used to render graphics for java swing components and also process all events corresponding to a keypress, mouse click or any action. 

So if you want to update a particular swing component suppose label of a JButton from Yes to No you need to do this in Event Dispatcher thread and for doing this you need InvokeLater. invokeLater is used to perform any task asynchronously on AWT Event Dispatcher thread.



What is invokeLater in Java Swing?

The invokeLater() is a method in java on swing package and belongs to the SwingUtilities class. Invokelater is used by java swing developer to update or perform any task on Event dispatcher thread asynchronously.invokeLater has been added into Java API from swing extension and it belongs to SwingUtilities class.


1. How do invokeLater works in Java Swing

If you see the signature of the invokeLater method you will find that invokeLater takes a Runnable object and queues it to be processed by EventDispatcher thread. EDT thread will process this request only after sorting out all AWT pending events or requests. 

Even if invokeLater is called directly form Event dispatches thread processing of Runnable task still be done only after processing all pending AWT Events. 

An important point to note is that in case if the run method of Runnable task throws an exception then AWT Event dispatcher thread will unwind and not the current thread.

2. Why do we need the InvokeAndWait method in Swing

As we know that Swing is not thread-safe and we can not update the Swing component or GUI from any thread. If you try to update GUI form any thread you will get unexpected results or exceptions, it could be your GUI might not be visible or simply disappeared. 

The only method which is thread-safe in the swing is a repaint() and revalidate(). On the other hand, InvokeAndWait allows us to update the GUI from EDT thread synchronously. InvokeAndWait method also belongs to swingUtility class like invokeLater.


3. How does InvokeAndWait work in Java Swing

If you look at the signature of the invokeAndWait method you will see that it takes a Runnable object and run method of that Runnable is executed synchronously on EDT. This is a blocking call and wait until all pending AWT events get processed and run() method completes. Its a preferred way of updating GUI form application thread.

An important point to note is that it should not be called from EventDispatcher thread unlike invokeLater; it’s an error because it will result in guaranteed deadlock

because if you cal invokeAndWait from EDT thread it will be an AWT event and caller of invokeAndWait will wait for EDT thread to complete and EDT will wait for caller thread to be completed so they will be locked in deadlock

It's also important to remember that if the run() method of Runnable object throws an exception then its caught in AWT EDT thread and rethrown as InvocationTargetException on the caller thread.

4. Example of InvokeLater in Java Swing

Here is an example of invokeLater() in Swing which will demonstrate that in the case of invokeLater application thread doesn’t block.

Runnable pickHighBetaStock = new Runnable() {
public void run() {
System.out.println("High beta Stock picked by  " + Thread.currentThread());
}
};

SwingUtilities.invokeLater(pickHighBetaStock);
System.out.println("This might well be displayed before the other message. if Event-dispatcher thread is busy");



5. Example of using InvokeAndWait in Java Swing

In this example of InvokeAndWait, we will see that the Application thread will block until the Runnable object passed to EDT has been executed.

final Runnable pennyStockPicker = new Runnable() {
public void run() {
System.out.println("pick penny Stock on " + Thread.currentThread());
}
};

Thread stockPicker = new Thread() {
public void run() {
try {
SwingUtilities.invokeAndWait(pennyStockPicker);
}
catch (Exception e) {
e.printStackTrace();
}
System.out.println("This will finish after pennyStockPicker thread because InvokeAndWait is block call" + Thread.currentThread());
}
};
stockPicker.start();




Difference on InvokeLater vs InvokeAndWait in Swing

Swingutilies provides us two methods for performing any task in the Event dispatcher thread. Now let's see what the difference between invokeLater and InvokeAndWait is and when to use invokeLater.

1) InvokeLater is used to perform a task asynchronously in AWT Event dispatcher thread while InvokeAndWait is used to perform task synchronously.

2) InvokeLater is a non-blocking call while InvokeAndWait will block until the task is completed.

3) If the run method of Runnable target throws an Exception then in the case of invokeLater EDT threads unwind while in the case of the invokeAndWait exception is caught and rethrown as InvocationTargetException.

4) InvokeLater can be safely called from the Event Dispatcher thread while if you call invokeAndWait from the EDT thread you will get an error because as per java documentation of invokeAndWait it clearly says that "this request will be processed only after all pending events" and if you call this from EDT this will become one of the pending events so its a deadlock because the caller of InvokeAndWait is waiting for the completion of invokeAndWait while EDT is waiting for the caller of InvokeAndWait.

5) InvokeLater is more flexible in terms of user interaction because it just adds the task in queue and allows the user to interact with the system while invokeAndWait is a preferred way to update the GUI from application thread.


In Summary, we can just say that since Swing is not thread-safe and we cannot update different Swing GUI components on any thread other than Event dispatcher Thread we need to use InvokeAndWait or InvokeLater to schedule any Runnable task for AWT Event dispatcher Thread. InvokeAndWait is synchronous and blocking call and waits until submitted Runnable completes while InvokeLater is asynchronous and non-blocking it will just submit task and exit."

That’s all on the InvokeAndWait() and InvokeLater() method of SwingUtilities class. They are very important while doing GUI programming on Swing as well as these is very popular interview questions that I have discussed in my latest post on swing interview questions asked in Investment banks.

Please let me know your experience with InvokeLater() and InvokeAndWait() method and any issues you found while using them which would worth be mentioning here.

Further Reading
How to override equals method in Java
What is Abstraction in java ?
How to convert String to int in Java

5 comments:

  1. InvokeAndWait and InvokeLater is also defined in EventQueue class and you should use directly from EventQueue instead of SwingUtilities. These two were part of SwingUtilities because first version of swing API had to work with JDK 1.1. even after now Swing is part of JDK they have remaining in SwingUtilities also.

    ReplyDelete
  2. This very same question difference between invokeAndWait and invokeLater is asked to me in a recent interview. there was also lots of followup in terms of blocking and how invokeAndWait achieves blocking etc.

    ReplyDelete
  3. One other point to note about invokeLater is that if you are calling it from a thread that gets processed on sub-second intervals you application will never terminate this is because the AWT Shutdown thread is kicked off every second and only terminates all the helper threads if there is nothing in the event queue. If you are calling invokeLater sub-second the event queue always has something in it. Nice little Gotcha ;)

    ReplyDelete
  4. Hi Steve, thanks for pointing this nice little Gotcha about AWT Shutdown thread, though I have not experienced it yet but worth trying.

    ReplyDelete
  5. what about synchronous and asynchronous in java?

    ReplyDelete