为什么SwingWorker意外停止了? [英] Why does SwingWorker stop unexpectedly?
问题描述
我想尝试一些使用 SwingWorker
的想法,因为我没有使用它太多。
这里是一个简短的 SSCCE 演示这个问题(我知道这里的人喜欢SSCCE):
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class SwingWorkerTest
{
public static void main(String [] args)
{
SwingUtilities.invokeLater(new Runnable b
@Override
public void run()
{
new MySwingWorker(500).execute();
new MySwingWorker(900).execute
new MySwingWorker(1200).execute();
}
});
}
}
类MySwingWorker扩展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
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println(我的线程是+ ms +休眠在迭代+ i +:+ t.getName()+ t.getId()+));
}
return null;
}
}
因此我的程序应该创建3个SwingWorkers打印一行然后在屏幕上睡眠指定的毫秒数,然后再次打印该行并再次睡眠等。我从Swing的线程创建 SwingWorker
s,否则他们不会甚至开始。
所以预期输出是:
线程500休眠在迭代0:SwingWorker-pool-1-thread-1(15)
我是线程900休眠在迭代0:SwingWorker-pool-1-thread-2(16)
我在线程500睡眠在迭代1:SwingWorker-pool-1-thread-1(15)
我是线程1200睡眠在迭代0:SwingWorker-pool-1-thread-3(17)
我在线程500休眠在迭代2:SwingWorker-pool-1-thread-1(15)
我是线程900休眠在迭代1:SwingWorker-pool-1-thread-2(16)
我在线程与500睡眠在迭代3:SwingWorker-pool-1-thread-1(15)
我是线程1200睡眠在迭代1:SwingWorker-pool-1-thread-3 17)
我在线程500休眠在迭代4:SwingWorker-pool-1-thread-1(15)
我是线程900休眠在迭代2:SwingWorker-pool-1-thread- 2(16)
我在线程有500睡眠在迭代5:SwingWorker-pool-1-thread-1(15)
我是线程500睡眠在迭代6:SwingWorker-我的线程有900睡眠在迭代3:SwingWorker-pool-1-thread-2(16)
我是线程1200睡眠在迭代2:SwingWorker-pool- 1-thread-3(17)
我在线程500次睡眠在迭代7:SwingWorker-pool-1-thread-1(15)
............ 。
等等,总共150行(每个3个工人x 50次迭代)相反,我得到的输出是:
睡眠在迭代0:SwingWorker-pool-1-thread-1(15)
我是线程900睡眠在迭代0:SwingWorker-pool-1-thread-2(16)
我是线程在迭代1中有500个睡眠:SwingWorker-pool-1-thread-1(15)
它。只有3行。之后程序退出。 try catch
块中没有堆栈跟踪。
1)。工人有1200ms的睡眠吗?实际上,如果我用1000ms替换1200ms,那么这个工人也打印1行...是的,只有一个。很奇怪...
2)。为什么工人停止? (我不会得到150行的东西)
我使用在Windows 7 64位的JRE 7 Update 11 64位运行此程序。
PS:我很确定这里提到的错误在这个版本的JRE中是固定的,因为我得到2个不同的值(15和16)作为打印在控制台上的线程ID。这是我怀疑的第一件事。
我相信你需要显示一个可视化的Swing顶级窗口, Swing事件线程活着。否则程序将由于缺少非守护线程而关闭。
编辑:
为了证明SwingWorker thread是一个Daemon线程,只是添加一行代码来测试它:
System.out.println ++(+ t.getId()+));+ ms +sleep in iteration
+ i +:+ t.getName
// **** added
System.out.println(Daemon ?:+ Thread.currentThread()。isDaemon());
I wanted to try out some ideas using SwingWorker
since I haven't used it too much. Instead, I ran into an issue and I can't figure out what's wrong.
Here's a short SSCCE that demonstrates this problem (I know people here like SSCCEs):
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;
}
}
So my program should create 3 SwingWorkers that print a line on the screen then sleep for the specified number of milliseconds and then print the line again and sleep again etc. I create the SwingWorker
s from within Swing's thread because otherwise they wouldn't even start.
So the expected output is:
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)
.............
and so on for a total of 150 lines (3 workers x 50 iterations for each)
Instead, the output I get is:
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)
And that's it. Just 3 lines. After this the program exits. There's no stacktrace anywhere from that try catch
block.
1). Where is the worker with the 1200ms sleep ? Actually, if I replace 1200ms with 1000ms, then this worker also prints 1 line... yes, only one. Weird...
2). Why do the workers stop ? (and I don't get 150 lines of stuff)
I ran this program using JRE 7 Update 11 on Windows 7 64-bit.
PS: I'm pretty sure that the bug mentioned here was fixed in this version of JRE, since I do get 2 distinct values (15 and 16) as thread ID's printed on the console. This was the first thing I suspected.
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());
这篇关于为什么SwingWorker意外停止了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!