SwingWorker: when exactly is called done method?

后端 未结 6 2089
遇见更好的自我
遇见更好的自我 2020-12-05 10:50

Javadoc of the done() method of SwingWorker:

Executed on the Event Dispatch Thread after the doInBackground method is

6条回答
  •  醉酒成梦
    2020-12-05 11:10

    When a thread is cancelled via

    myWorkerThread.cancel(true/false);
    

    the done method is (quite surprisingly) called by the cancel method itself.

    What you may expect to happen, but actually DOESN'T:
    - you call cancel (either with mayInterrupt or not)
    - cancel set up the thread cancellation
    - the doInBackground exits
    - the done is called*
    (* the done is enqueued to the EDT, that means, if EDT is busy it happens AFTER the EDT has finished what it is doing)

    What actually DOES happen:
    - you call cancel (either with mayInterrupt or not)
    - cancel set up the thread cancellation
    - the done is called as part of cancel code*
    - the doInBackground will exit when it will have finished its loop
    (*the done isn't enqueued to the EDT, but called into the cancel call and so it has a very immediate effect on EDT, that often is the GUI)

    I provide a simple example that proves this.
    Copy, paste and run.
    1. I generate a runtime exception inside done. The stack thread shows that done is called by cancel.
    2. About after 4 seconds after cancelation, you'll recive a greeting from the doInBackground, that fhurterly proves that done is called before the thread exiting.

    import java.awt.EventQueue;
    import javax.swing.SwingWorker;
    
    public class SwingWorker05 {
    public static void main(String [] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                W w = new W();
                w.execute();
                Thread.sleep(1000);
                try{w.cancel(false);}catch (RuntimeException rte) {
                    rte.printStackTrace();
                }
                Thread.sleep(6000);
                } catch (InterruptedException ignored_in_testing) {}
            }
    
        });
    }
    
    public static class W extends SwingWorker  {
    
        @Override
        protected Void doInBackground() throws Exception {
            while (!isCancelled()) {
                Thread.sleep(5000);
            }
            System.out.println("I'm still alive");
            return null;
        }
    
        @Override
        protected void done() {throw new RuntimeException("I want to produce a stack trace!");}
    
    }
    
    }
    

提交回复
热议问题