2

I just solved the problem myself. I had multiple calls for syncCustomers() due to a dialog closing event problem. I solved it by providing the parent JFrame in the JDialog constructor. Pretty stupid error on my side.

My application contains a task that synchronizes with a webservice and a local database. This task may take up to several minutes. Thus I want to notify the user about this time consuming process with a simple dialog (Swing). The user is not supposed to continue working while the sync process is running.

So I thought of:

  1. open modal dialog with the notification for the user
  2. start the sync process in a separate thread
  3. close modal dialog after sync process is done

User clicked on the button to start sync process:

private void syncCustomers() {
    if (checkWebserviceAuth()) {

        SyncDialog dialog = new SyncDialog();
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);

        SyncCustomersTask task = new SyncCustomersTask(dialog, getCoach());
        task.run(); // task.start() will result in the same problem

    } else {
        openAuthorizeDialog(true);
    }
}

public class SyncDialog extends javax.swing.JDialog {

    public SyncDialog() {
        initComponents();
        // I already noticed that the modal dialog won't work for me since it interrupts within syncCustomers()
        //this.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);

        this.setTitle(Application.getApplicationTitle());
    }

    ...

}

public class SyncCustomersTask extends Thread {

    private void doWork() {
        System.out.println("Start doWork() and sleep for 10 seconds...");
        try {
            // for testing purpose
            Thread.sleep(10000);
        } catch (InterruptedException ex) {
        }
        System.out.println("Done with doWork().");
    }

    @Override
    public void run() {
        doWork();
        if (getCallback() != null) {
            System.out.println("Invoke callback...");
            getCallback().dispose();
            System.out.println("Callback invoked.");
        }
    }

    ...
}

This will result in an infinite loop of:

Start with doWork()...
Start doWork() and sleep for 10 seconds...
Done with doWork().
Invoke callback...
Callback invoked.

If I comment out

getCallback().dispose();

, the loop will stop after the second execution:

Start with doWork()...
Start doWork() and sleep for 10 seconds...
Done with doWork().
Invoke callback...
Callback invoked.
Start with doWork()...
Start doWork() and sleep for 10 seconds...
Done with doWork().
Invoke callback...
Callback invoked.

I don't get it. What fires the thread to execute over and over again?

I guess this whole thing isn't a good idea to start with, but I wasn't able to get things like ProgressMonitor working either. :(

4

2 回答 2

2

打电话start(),不是run()。后者将简单地执行线程,而不是在单独的线程中!该start()方法将实例化一个新线程,然后才run()在该新线程中调用您的方法。

顺便说一句,这是一个令人惊讶的常见问题。

于 2013-02-22T11:25:08.080 回答
0

调用run()不会在新线程中执行代码。

于 2013-02-22T11:26:30.397 回答