Why does SwingWorker stop unexpectedly?

萝らか妹 提交于 2019-11-28 01:54:44

I believe that you need to show a visualized Swing top level Window in order to keep the Swing event thread alive. Otherwise the program will shut down for lack of non-daemon threads.

Edit:
To prove that the SwingWorker thread is a Daemon thread, just add a line of code to test it:

System.out.println("I am thread with " + ms + " sleep in iteration "
   + i + ": " + t.getName() + " (" + t.getId() + ")");

// **** added
System.out.println("Daemon?: " + Thread.currentThread().isDaemon()); 

If you look at line 771 of SwingWorker class source code (Java SE 7):

thread.setDaemon(true);

You will see that the SwingWorker is executed within a daemon thread, and in Java the JVM will be terminated if all non-daemon threads are finished.

As already mentioned, you can use the UI to keep the threads alive.

Alternatively, what you can do is use SwingWorker#get (or anything that prevents the main thread from terminating) to wait for the threads to finish. By doing so, you will get the output as expected. Here is the modified code, that does what you want.

import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import java.util.concurrent.ExecutionException;

public class SwingWorkerTest
{
    public static void main (String[] args)
    {
        final MySwingWorker w1 = new MySwingWorker (500),
         w2 = new MySwingWorker (900),
         w3 = new MySwingWorker (1200);
        SwingUtilities.invokeLater (new Runnable ()
        {
            @Override
            public void run ()
            {
                w1.execute ();
                w2.execute ();
                w3.execute ();
            }
        });

        try{
            // you can replace the code in this block
            // by anything that keeps the program from 
            // terminating before the threads/SwingWorkers.
            w1.get();
            w2.get(); 
            w3.get(); 
        }catch(InterruptedException e){
            System.err.println("InterruptedException occured");
        }catch(ExecutionException e){
            System.err.println("InterruptedException occured");
        }

    }
}

class MySwingWorker extends SwingWorker<Void, Void>
{
    private int ms;

    public MySwingWorker (int ms)
    {
        this.ms = ms;
    }

    @Override
    protected Void doInBackground()
    {
        Thread t = Thread.currentThread ();

        for (int i = 0; i < 50; i++)
        {
            try
            {
                Thread.sleep (ms);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace ();
            }

            System.out.println ("I am thread with " + ms + " sleep in iteration " + i + ": " + t.getName () + " (" + t.getId () + ")");
        }

        return null;
    }
}

Have you tried creating any UI? or putting something like new Object().wait(); at the end of main, to prevent the main thread from exiting?

I'm not entirely sure that this is the case, but without any actual UI showing, i'm pretty sure the swing workers are just another thread, and you haven't configured any as daemon threads, so main starts them up, main finishes, and the process exits?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!