Wednesday, September 14, 2011

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 first part we will mostly focus on invokeLater and will find answers of questions like What is invokeLater, how to use invokelater in java swing, example of invokelater in swing etc while in 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 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 end of article.


Outline

Why do we need 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 swingutility class? As we all know java swing is not threadsafe , you can not update swing component like JButton, JLable , JTable or JTree from any thread , they all needs 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 component and also process all events corresponding to key press, 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


Invokelater is a method in java on swing package and belongs to 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’s belong to SwingUtilities class.


How does invokeLater works in Java Swing


If you see the signature of 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 run method of Runnable task throw any exception then AWT Event dispatcher thread will unwind and not the current thread.

Why do we need 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 result or exception, it could be your GUI might not be visible or simply disappered. Only method which is thread-safe in swing is 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.


How does InvokeAndWait works in Java Swing


If you look at the signature of 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 gets processed and run() method completes. Its a preferred way of updating GUI form application thread.

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 caller thread to be completed so they will be locked in deadlock. Its also important to remember that if run() mehtod of Runnable object throw exception then its caught in AWT EDT thread and rethrown as InvocationTargetException on caller thread.

Example of InvokeLater in Java Swing


Here is an example of invokeLater() in Swing which will demonstrate that in 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");


Example of using InvokeAndWait in Java Swing


In this example of InvokeAndWait we will see that Application thread will block until 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 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 task asynchronously in AWT Event dispatcher thread while InvokeAndWait is used to perform task synchronously.

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

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

4) InvokeLater can be safely called from Event Dispatcher thread while if you call invokeAndWait from 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 pending event so its a deadlock because caller of InvokeAndWait is waing for completion of invokeAndWait while EDT is waiting for caller of InvokeAndWait.

5) InvokeLater is more flexible in terms of user interaction because it just adds the task in queue and allow user to interact with system while invokeAndWait is preffered 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 wait until submitted Runnable completes while InvokeLater is asynchronous and non-blocking it will just submit task and exit."

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

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


Some of my other tutorial in Java

5 comments :

Anonymous said...

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.

Anonymous said...

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.

Steve Webb said...

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

Javin @ java final keyword example said...

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

satheesh kumar said...

what about synchronous and asynchronous in java?

Post a Comment