Tuesday, August 26, 2014

Thread Handling in Eclipse UI

Threads in Eclipse UI environment is mainly of 2 types:
1.       UI Thread
2.       Non UI Thread.

1.   UI Thread : The UI thread is the thread in which the Display was created. And All other widgets must be created in the UI thread. So if we create a Display, then shell, then add some widgets to it , etc, all these activity is happening in UI Thread.
Executing critical long process in UI thread may freeze the UI and lead to bad user experience.
Long operations triggered by UI events should be performed in a separate thread in order to allow the event loop thread to return quickly and fetch the next event from the application's queue.
public static void main (String [] args) {
      Display display = new Display ();
      Shell shell = new Shell (display);
      shell.open ();
      // start the event loop. We stop when the user has done
      // something to dispose our window.
      while (!shell.isDisposed ()) {
         if (!display.readAndDispatch ())
            display.sleep ();
      }
      display.dispose ();
   }

Note: SWT will trigger an SWTException for any calls made from a non-UI thread that must be made from the UI thread.

2.   Non UI Thread : Those thread which does not involve any UI activity creation or disposal or any kind of integration. So, technically speaking, all threads which are not UI thread will be called NON UI thread.


What to do in situation when we need to run a UI thread code from Non UI thread?

So if we directly call UI Thread method from Non UI Thread, then it will throw SWTException. So, to overcome this We must provide runnables to this Non UI thread to call UI code. There are 2 ways given by Display to execute these runnables:

·         Display.getDefault().syncExec(Runnable)
·         Display. getDefault().asyncExec(Runnable)



syncExec(Runnable): This method is used to run the code when we want parent thread to wait until this runnable has exceuted. Eg: If my parent thread wants dialogsize for some processing and this size is coming from the runnable, then parent thread will wait until runnable returns the dialog size to execute further.

Display.getDefault().syncExec(new Runnable() {
                                           
                                            @Override
                                            public void run() {
                                                   
                                            //Your UI code goes here.
                                            }
                                   });

asyncExec(Runnable): This method is called when application wants to process some UI operation but is not dependent on any activity of runnable.

Display.getDefault().asyncExec(new Runnable() {
                                           
                                            @Override
                                            public void run() {
                                                   
                                                    //Your UI code goes here.
                                            }
                                   });