繁体   English   中英

从syncExec返回变量的最佳方法是什么?

[英]What's the best way to return variables from a syncExec?

在我的SWT Java应用程序中,我经常想从Display.syncExec()调用中返回信息。 到目前为止,我发现这样做的最好方法是:

final ArrayList<Integer> result = new ArrayList<Integer>();
GUI.display().syncExec(new Runnable(){ public void run() {
   MessageBox mb = /* ... */;
    /* set up messagebox */
   result.add(mb.open());
}});
if (SWT.OK == result.get(0)) { /* ... */ }

我认为这是允许的,因为ArrayList是线程安全的,但是我应该使用更好的容器,还是更简单的方法?

ArrayList不是线程安全的 您可以使用Collections.synchronizedList获取线程安全的List 但是,在更常见的情况下,在您的案例或AtomicReference中使用AtomicInteger要简单得多。

final AtomicInteger resultAtomicInteger = new AtomicInteger();
Display.getCurrent().syncExec(new Runnable() { 
    public void run() {
        MessageBox mb = /* ... */;
            /* set up messagebox */
        resultAtomicInteger.set(mb.open());
}});
if (SWT.OK == resultAtomicInteger.get()) { /* ... */ }

我刚刚解决了这个问题,我的第一次尝试是类似的 - 数组或所需类型项的列表。 但过了一段时间我做了这样的事情:

abstract class MyRunnable<T> implements Runnable{
    T result;
}
MyRunnable<Integer> runBlock = new MyRunnable<Integer>(){
   MessageBox mb = /* ... */;
    /* set up messagebox */
   result = mb.open();
}
GUI.display().syncExec(runBlock);
runBlock.result; //holds a result Integer

它更加整洁并消除了冗余变量。

BTW。 我真正的第一次尝试是使用UIThreadRunnable,但我不想要SWTBot依赖,所以我放弃了这个解决方案。 在我找到自己的解决方案后,我发现,他们在那里使用类似的工作。

如果经常发生这种情况,最好在进程和视图之间使用subscribe / notify模型。 您的视图订阅了应触发该消息框的事件,并在满足条件时收到通知。

ArrayList 不是线程安全的。 来自相关的Javadoc

请注意,此实现不同步。 如果多个线程同时访问ArrayList实例,并且至少有一个线程在结构上修改了列表,则必须在外部进行同步。

如果需要List的线程安全实现,JDK中提供了(至少)两个:CopyOnWriteArrayList和Vector。

您可以使用Integer [1]数组使其更简洁,但我认为它不能直接从匿名内部类中更新非final变量。

final Integer[] result = new Integer[1];

我认为您必须将结果声明为final(但该更改不会影响您的代码)。 由于当前线程阻塞直到内部线程完成,我认为您不必担心同步(但您可能需要使变量违反,以便您看到结果)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM