簡體   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