5

Edit : I have referred this link and I'm able to understand the codeflow of InvokeLater. My question is, why is this logic implemented this way? Are there any specific reasons?


Following is my code:

  private void init() 
    {
    JFrame jfr = new JFrame();
    jfr.setSize(500, 500);
    jfr.setVisible(true);
    jfr.setTitle("Test");


    JButton jb = new JButton("Ok");
    jfr.add(jb);

    jb.addActionListener(new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            try 
            {
                SwingUtilities.invokeAndWait(new Runnable() 
                {
                    @Override
                    public void run() 
                    {
                        System.out.println("hello");
                    }
                });
            } 
            catch (Exception e1) 
            {
                e1.printStackTrace();
            } 
        }
    });

First Question (While using InvokeAndWait):

Why is it implemented in such a way that it throws an InvocationTargetException when called within EDT Thread?

Second Question (while using InvokeLater):

Why InvokeLater allows this ?

Well, this is my basic understanding on EDT threads:

InvokeAndWait:

  • Places job F into the EDT event queue and waits until the EDT has executed it.
  • This call blocks until all pending AWT events(A, B, C, D, E) have been processed and (then) execute F after which the control returns.
  • Returns if and only if the job submitted is completed.(Control returns after F is completed.)
  • Technically, a Synchronous blocking call.

InvokeLater:

  • Places the job F into the EDT Queue , but doesn't wait for its completion.(Basically , a publish and return call).
  • If we don't care about the job completion we can use InvokeLater.
  • Technically, a Asynchronous non-blocking call.
Community
  • 1
  • 1
Diya
  • 127
  • 1
  • 9
  • 3
    Possible duplicate of [invokeAndWait method in SwingUtilities](http://stackoverflow.com/questions/5499921/invokeandwait-method-in-swingutilities) – Sanjeev Jul 11 '16 at 11:23

1 Answers1

5

EDT is the same as AWT. All UI events in AWT are scheduled on a single thread called EDT. Basically is the thread used to process UI related events in Swing.

InvokeAndWait: Basically you invoke a task on the same thread and then wait for that task to be completed. This would result in deadlock. Your method will never return cuz you are waiting for the task, the task will never run because your method will never be completed.

InvokeLate: It works because you are not waiting for that task to be completed. You invoke it in the exact same thread, but you are not waiting for it to complete, so this won't result in deadlock.

Arpad Toth
  • 231
  • 2
  • 6
  • 1
    To be fair it'd be really simple to avoid the deadlock (you are already on the right thread just execute the code directly), but you should generally know whether you are on the GUI thread or not so this would just support lazy programming – Voo Jul 11 '16 at 11:32
  • 1
    In fact you can't do this as easily as you think. Almost all frameworks uses a single rendering **QUEUE** for a reason. You may have scheduled thousands tasks that **must** be executed before yours. You can't just insert or execute random tasks at random points and except it to work. Some calculations depend on each other. The problem of multi threading UI is very deep and can result in rendering and debugging nightmares. That's why some clever developers decided that UI must be done all in a single thread and the UI tasks must be executed in a **QUEUE**, in a specific order. – Arpad Toth Jul 11 '16 at 11:45
  • Is there actually any documentation in which order events are executed? Not that I know of. Win32 for example doesn't give you any such guarantees as far as I know and as a matter of fact doesn't actually have *one* queue (if you want you can say it has two). If no specific order is guaranteed then this would be perfectly acceptable behavior. – Voo Jul 11 '16 at 13:34
  • I don't know of any documentation but I know that the decision of making most UI frameworks single threaded is because managing a multi threaded rendering engine is a nightmare and the benefits are not so great. Is a matter of complexity, is really hard to do it right and is harder for casual developers to understand all the insights. You can read more about this here: https://msdn.microsoft.com/en-us/library/ms810439.aspx or https://community.oracle.com/blogs/kgh/2004/10/19/multithreaded-toolkits-failed-dream – Arpad Toth Jul 11 '16 at 13:50
  • Yeah because it's really hard to get the internal synchronization right. That doesn't matter in this case though obviously. I doubt that there's any guarantee that events are executed in the same order as they arrive and most likely some events are "queued" with different priorities so you shouldn't rely on this to begin with. – Voo Jul 11 '16 at 14:23
  • It actually is, let me give you one example: We have a mouse, one button and 3 threads. One thread processes the mouse, and two threads attempts to repaint the button. In case you don't sequentialise the UI operations you end up with one thread painting half a button, another thread painting the other half and none of them acknowledging that the mouse is over and they should paint the button with highlight. The only way to achieve this is by synchronizing the 3 threads with the added complexity. But if you synchronize the code, you are actually simulating a queue. – Arpad Toth Jul 11 '16 at 15:04
  • 1
    `All UI events are scheduled on a single thread called AWT` - The Thread is called the Event Dispatch Thread (EDT), not AWT. AWT is a toolkit not a Thread. – camickr Jul 11 '16 at 15:04
  • @camickr Thanks for the correction:) Indeed AWT is the toolkit. I edited my answer accordingly. As a curiosity, many Java developers refers to the EDT as "AWT thread" because the name of the thread is something like "AWT-EventQueue-0". Basically it is the thread that the AWT operations are executed on. I confess, I often use the term "AWT thread". – Arpad Toth Jul 11 '16 at 15:20
  • @Arpad You're confusing two totally different things: All actions are executed on the GUI thread, there's no question about that. But you haven't shown any documentation that guarantees that if you queue several events that these will be executed in the same order on the GUI thread (even if it were documented, you could document `InvokeAndWait` to provide the same guarantees as SendMessage on Win32) – Voo Jul 11 '16 at 16:15
  • @Voo I hope you are kidding (or trolling) me. This is elementary stuff. By definition a queue structure will assure that the tasks will be executed **in order**. Check what a queue actually is: https://en.wikipedia.org/wiki/Queue_(abstract_data_type). Yes you can have multiple queues for multiple priorities, but the tasks with the same priority will be executed in order, sequentially. While you can schedule tasks from multiple threads, the fact that these tasks can't run and alter the UI, concurrently, fixes a lot of issues that may occur in case you use a multi threaded UI framework. I – Arpad Toth Jul 11 '16 at 16:29
  • @arpad and now show me the specification where it says that events are handled in a first in first out manner. – Voo Jul 11 '16 at 20:24