为什么SwingWorker会意外停止?

Rad*_*zea 8 java concurrency swing multithreading swingworker

我想尝试使用一些想法,SwingWorker因为我没有太多使用它.相反,我遇到了一个问题,我无法弄清楚出了什么问题.

这是一个简短的SSCCE来演示这个问题(我知道这里的人像SSCCE一样):

import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我的程序应该创建3个SwingWorkers,在屏幕上打印一行,然后睡眠指定的毫秒数,然后再次打印该行并再次睡眠等.我SwingWorker从Swing的线程中创建s,否则它们甚至不会启动.

所以预期的输出是:

I am thread with 500 sleep in iteration 0: SwingWorker-pool-1-thread-1 (15)
I am thread with 900 sleep in iteration 0: SwingWorker-pool-1-thread-2 (16)
I am thread with 500 sleep in iteration 1: SwingWorker-pool-1-thread-1 (15)
I am thread with 1200 sleep in iteration 0: SwingWorker-pool-1-thread-3 (17)
I am thread with 500 sleep in iteration 2: SwingWorker-pool-1-thread-1 (15)
I am thread with 900 sleep in iteration 1: SwingWorker-pool-1-thread-2 (16)
I am thread with 500 sleep in iteration 3: SwingWorker-pool-1-thread-1 (15)
I am thread with 1200 sleep in iteration 1: SwingWorker-pool-1-thread-3 (17)
I am thread with 500 sleep in iteration 4: SwingWorker-pool-1-thread-1 (15)
I am thread with 900 sleep in iteration 2: SwingWorker-pool-1-thread-2 (16)
I am thread with 500 sleep in iteration 5: SwingWorker-pool-1-thread-1 (15)
I am thread with 500 sleep in iteration 6: SwingWorker-pool-1-thread-1 (15)
I am thread with 900 sleep in iteration 3: SwingWorker-pool-1-thread-2 (16)
I am thread with 1200 sleep in iteration 2: SwingWorker-pool-1-thread-3 (17)
I am thread with 500 sleep in iteration 7: SwingWorker-pool-1-thread-1 (15)
.............
Run Code Online (Sandbox Code Playgroud)

等等共计150行(3名工人×每次50次迭代)

相反,我得到的输出是:

I am thread with 500 sleep in iteration 0: SwingWorker-pool-1-thread-1 (15)
I am thread with 900 sleep in iteration 0: SwingWorker-pool-1-thread-2 (16)
I am thread with 500 sleep in iteration 1: SwingWorker-pool-1-thread-1 (15)
Run Code Online (Sandbox Code Playgroud)

就是这样.只需3行.在此之后程序退出.该try catch块中没有任何堆栈跟踪.

1).睡眠时间为1200毫秒的工人在哪里?实际上,如果我用1000毫秒替换1200毫秒,那么这个工作人员也打印1行......是的,只有一行.奇怪的...

2).为什么工人会停下来?(我没有得到150行的东西)

在Windows 7 64位上使用JRE 7 Update 11运行此程序.

PS:我很确定这里提到的bug是在这个版本的JRE中修复的,因为我确实得到了2个不同的值(15和16)作为线程ID打印在控制台上.这是我怀疑的第一件事.

Hov*_*els 9

我相信你需要显示一个可视化的Swing顶级窗口,以保持Swing事件线程的活动.否则程序将因缺少非守护程序线程而关闭.

编辑:
要证明SwingWorker线程是一个守护程序线程,只需添加一行代码来测试它:

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

// **** added
System.out.println("Daemon?: " + Thread.currentThread().isDaemon()); 
Run Code Online (Sandbox Code Playgroud)


Eng*_*uad 9

如果你看一下SwingWorker类源代码(Java SE 7)的第771行:

thread.setDaemon(true);
Run Code Online (Sandbox Code Playgroud)

您将看到SwingWorker在守护程序线程中执行,并且在Java中,如果所有非守护程序线程都已完成,则JVM将终止.

  • 神圣的废话,你们是对的.SwingWorkers作为守护程序线程运行.这甚至没有让我想到.谢谢你,StackOverflow,你总能找到答案:D. (4认同)