在 syncExec 块内外使用变量的最简单方法(或者,如何在不初始化的情况下存储对对象的最终引用)
Simplest way to use variable inside and outside a `syncExec` block (or, how to store a final reference to an object without initializing)
我在这个例子中成功地使用了 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);
它在 getSomeCustom()
调用时输出 The final local variable view cannot be assigned, since it is defined in an enclosing type
。
我也尝试过使用 Reference
及其实现,但它们似乎不是我要找的东西(这是最可读和最基本的方法)。有人知道如何在不使用 AtomicReference
的情况下实现这一目标吗?
管理此问题的最简单方法是拥有一个可以放入某些内容的最终变量。例如:
final Custom[] customHolder = new Custom[1];
PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
customHolder[0] = getSomeCustom();
customHolder[0].doSomething();
});
customHolder[0].doSomethingElse(true);
只要保证在下一行之前调用 lambda 函数(即,如果 syncExec
阻塞了线程,我相信它确实如此),这将起作用。
我建议定义一个接受 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];
}
}
使用one-element数组有点脏,但是你只需要写一次这个方法。之后你可以使用:
Custom c = UIUtils.syncExec(() -> {
Custom custom = getSomeCustom();
custom.doSomething();
return custom;
});
c.doSomethingElse();
我在这个例子中成功地使用了 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);
它在 getSomeCustom()
调用时输出 The final local variable view cannot be assigned, since it is defined in an enclosing type
。
我也尝试过使用 Reference
及其实现,但它们似乎不是我要找的东西(这是最可读和最基本的方法)。有人知道如何在不使用 AtomicReference
的情况下实现这一目标吗?
管理此问题的最简单方法是拥有一个可以放入某些内容的最终变量。例如:
final Custom[] customHolder = new Custom[1];
PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
customHolder[0] = getSomeCustom();
customHolder[0].doSomething();
});
customHolder[0].doSomethingElse(true);
只要保证在下一行之前调用 lambda 函数(即,如果 syncExec
阻塞了线程,我相信它确实如此),这将起作用。
我建议定义一个接受 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];
}
}
使用one-element数组有点脏,但是你只需要写一次这个方法。之后你可以使用:
Custom c = UIUtils.syncExec(() -> {
Custom custom = getSomeCustom();
custom.doSomething();
return custom;
});
c.doSomethingElse();