从UI线程调用PlatformUI.getWorkbench()。getDisplay()。syncExec

时间:2014-01-27 16:10:14

标签: eclipse multithreading swt

我见过:

if (Display.getCurrent() == null){
   PlatformUI.getWorkbench().getDisplay.asyncExec(aRunnable)
} else {
   aRunnable.run();
}

我想知道是否真的需要手动检查当前的执行线程。如果我无条件使用

PlatformUI.getWorkbench().getDisplay.asyncExec(aRunnable)

显示实现不会正确处理这两种情况吗?如果是这样,将asyncExec替换为syncExec时,它是否也能正确处理?

2 个答案:

答案 0 :(得分:2)

它是一个实现细节,当从UI线程调用时syncExecasyncExec如何操作。 documentation州:

  

导致runnable的run()方法在下一个合理的机会由用户界面线程调用。

这意味着您的Runnable可以简单地放入队列并在下一个调度循环中执行,可能落后于其他Runnable。如果您在UI线程上专门调用run的{​​{1}}方法,那么您可以更好地控制其调度。

当然,从UI线程调用时,RunnablesyncExec的行为可能会有所不同。我似乎记得asyncExec将在从UI线程调用时立即执行,并且syncExec将始终对其工作进行排队,但同样,这是一个实现细节,并不能保证。

此外,,您无法使用asyncExec的实例替换asyncExec的每个实例。 syncExec将等待UI线程发布和执行有问题的runnable,这可能会造成严重的争用问题。想象一下这个代码在非UI线程上运行:

syncExec

这是一个微不足道的例子 - 但它不会死锁。 synchronized(foo) { display.asynExec(new Runnable() { public void run() { synchronized(foo) { System.out.println("Hello!"); } } }); } 调用将对此runnable进行排队并返回,这将从asyncExec块中删除,以便UI线程上的runnable可以稍后获得锁定。但是,用synchronized替换它肯定会陷入僵局。

一般情况下,建议使用syncExec,除非您认为自己需要asyncExec所做的执行保证。

答案 1 :(得分:1)

SWT的显示将正确处理syncExecasyncExec,无论是从UI线程还是其他线程调用它们。

如果你真的希望避免调用这些API的微小开销并且喜欢在发布的代码上执行同步执行,那么进行这样的检查是有意义的。