编辑:我已经推荐了这个link,我能够理解InvokeLater的代码流.我的问题是,为什么这种逻辑以这种方式实现?有什么具体原因吗?
以下是我的代码:
private void init()
{
JFrame jfr = new JFrame();
jfr.setSize(500, 500);
jfr.setVisible(true);
jfr.setTitle("Test");
JButton jb = new JButton("Ok");
jfr.add(jb);
jb.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
try
{
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run()
{
System.out.println("hello");
}
});
}
catch (Exception e1)
{
e1.printStackTrace();
}
}
});
第一个问题(使用InvokeAndWait时):
为什么它以在EDT Thread中调用时抛出InvocationTargetException的方式实现?
第二个问题(使用InvokeLater时):
为什么InvokeLater允许这个?
嗯,这是我对EDT线程的基本理解:
InvokeAndWait:
>将作业F放入EDT事件队列并等待直到EDT
执行它.
>此调用将阻止,直到所有挂起的AWT事件(A,B,C,D,E)都有
已处理并(然后)执行F后控制
回报.
>当且仅当提交的作业完成时才返回.(控制
F完成后返回.)
>从技术上讲,是一个同步阻塞调用.
invokeLater的:
>将作业F放入EDT队列,但不等待它
完成.(基本上,发布和回访).
>如果我们不关心作业完成,我们可以使用InvokeLater.
>从技术上讲,是一种异步非阻塞调用.
解决方法:
EDT与AWT相同. AWT中的所有UI事件都安排在名为EDT的单个线程上.基本上是用于在Swing中处理UI相关事件的线程.
InvokeAndWait:基本上你在同一个线程上调用一个任务,然后等待该任务完成.这会导致死锁.您的方法永远不会返回,因为您正在等待任务,任务将永远不会运行,因为您的方法永远不会完成.
InvokeLate:它的工作原理是因为您没有等待完成该任务.你在完全相同的线程中调用它,但你不是在等它完成,所以这不会导致死锁.