Uri*_*Uri 6 eclipse eclipse-plugin anonymous-class
我正在编写Eclipse插件,并且经常出现这样的情况,即正在运行的Job需要暂停一段时间,在UI线程上异步运行并恢复.
所以我的代码通常看起来像:
Display display = Display.getDefault();
display.syncExec(new Runnable() {
public void run() {
// Do some calculation
// How do I return a value from here?
}
});
// I want to be able to use the calculation result here!
Run Code Online (Sandbox Code Playgroud)
一种方法是让整个Job类都有一些字段.另一种方法是使用自定义类(而不是匿名类,并使用其生成的数据字段等.什么是最好和最优雅的方法?
我认为上面的容器是"正确的"选择.它也可以是类型安全的通用化.在这种情况下的快速选择是最终的数组习语.诀窍是从Runnable引用的任何局部变量必须是最终的,因此不能修改.因此,您使用单个元素数组,其中数组是final,但可以修改数组的元素:
final Object[] result = new Object[1];
Display display = Display.getDefault();
display.syncExec(new Runnable()
{
public void run()
{
result[0] = "foo";
}
}
System.out.println(result[0]);
Run Code Online (Sandbox Code Playgroud)
同样,对于那些您拥有匿名类并且希望在不定义特定Container类的情况下为其提供结果的情况,这是"快速"解决方案.
更新 在我想到这一点后,我意识到这适用于回调在同一个线程中的监听器和访问者类型用法.但是,在这种情况下,Runnable在另一个线程中执行,因此无法保证在syncExec返回后实际看到结果.正确的解决方案是使用AtomicReference:
final AtomicReference<Object> result = new AtomicReference<Object>();
Display display = Display.getDefault();
display.syncExec(new Runnable()
{
public void run()
{
result.set("foo");
}
}
System.out.println(result.get());
Run Code Online (Sandbox Code Playgroud)
所有线程都保证可以看到对AtomicReference值的更改,就像它被声明为volatile一样.这详细描述在这里.
您可能不应该假设异步Runnable
将在调用返回时完成asyncExec
。
在这种情况下,您正在考虑将结果推送到侦听器/回调(可能是命令模式),或者如果您确实希望稍后在同一方法中使用结果,请使用java.util.concurrent.Future
.
归档时间: |
|
查看次数: |
2811 次 |
最近记录: |