在`syncExec`块内外使用变量的最简单方法(或者,如何在不初始化的情况下存储对象的最终引用)

时间:2016-01-15 12:16:18

标签: java eclipse swt

我在这个例子中成功使用AtomicReference(我发现第一个有效且可读的东西),但由于我还使用syncExec,因此无法访问同步块外的部分直到块完成执行,我真的不需要引用是原子的。这似乎有点矫枉过正。

final AtomicReference<Custom> result = new AtomicReference<>();

PlatformUI.getWorkbench().getDisplay().syncExec( () -> {
    Custom custom = getSomeCustom();
    custom.doSomething();
    result.set(custom);
});

Custom c = result.get();
c.doSomethingElse();

我尝试使用常规引用,但我无法让它工作:

final Custom c;

PlatformUI.getWorkbench().getDisplay().syncExec( () -> {
    c= getSomeCustom();
    c.doSomething();
});

c.doSomethingElse(true);

它在The final local variable view cannot be assigned, since it is defined in an enclosing type电话上输出getSomeCustom()

我也尝试过使用Reference及其实现,但它们似乎并不是我想要的(这是最可读和最基本的方法)。有没有人知道如何在不使用AtomicReference的情况下实现这一目标?

2 个答案:

答案 0 :(得分:2)

我建议定义一个接受Supplier的自定义静态方法:

public class UIUtils {
    static <T> T syncExec(Supplier<T> supplier) {
        Object[] obj = new Object[1];
        PlatformUI.getWorkbench().getDisplay().syncExec( () -> {
            obj[0] = supplier.get();
        });
        return (T)obj[0];
    }
}

使用单元素数组有点脏,但是你只需要编写一次这个方法。之后你可以使用:

Custom c = UIUtils.syncExec(() -> {
    Custom custom = getSomeCustom();
    custom.doSomething();
    return custom;
});

c.doSomethingElse();

答案 1 :(得分:1)

管理这个的最简单方法是拥有一个可以放入内容的最终变量。例如:

final Custom[] customHolder = new Custom[1];

PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
    customHolder[0] = getSomeCustom();
    customHolder[0].doSomething();
});

customHolder[0].doSomethingElse(true);

只要保证在下一行之前调用lambda函数(即如果syncExec阻塞线程,我相信它会这样做),那将会有效。