2

私の 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 はスレッドセーフであるため、これは許可されていると思いますが、使用する必要があるより良いコンテナー、または完全に簡単な方法はありますか?

4

5 に答える 5

5

ArrayListはスレッドセーフではありませんListでスレッドセーフを取得できますCollections.synchronizedListAtomicIntegerただし、あなたのケースまたはAtomicReferenceより一般的なケースでを使用する方がはるかに簡単です。

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()) { /* ... */ }
于 2008-09-16T20:13:55.767 に答える
3

私はこの問題に取り組みましたが、最初の試みは似ていました-目的のタイプ項目の配列またはリスト。しかし、しばらくすると、次のようなものを作成しました。

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

はるかに整頓されており、冗長な変数が削除されています。

ところで。私の本当に最初の試みは UIThreadRunnable を使用することでしたが、SWTBot の依存関係が欲しくなかったので、このソリューションを削除しました。私が見つけた独自のソリューションを作成した後、彼らはそこで同様の作業を使用しています。

于 2012-01-20T12:28:41.010 に答える
1

これが頻繁に発生する場合は、プロセスとビューの間でサブスクライブ/通知モデルを使用することをお勧めします。ビューは、そのメッセージ ボックスをトリガーするイベントをサブスクライブし、条件が満たされたときに通知を受け取ります。

于 2008-09-19T11:58:31.913 に答える
1

ArrayList はスレッドセーフではありません。関連するJavadocから:

この実装は同期されていないことに注意してください。複数のスレッドが ArrayList インスタンスに同時にアクセスし、少なくとも 1 つのスレッドがリストを構造的に変更する場合は、外部で同期する必要があります。

List のスレッドセーフな実装が必要な場合、JDK には (少なくとも) 2 つ、CopyOnWriteArrayList と Vector が用意されています。

于 2008-09-16T20:09:47.897 に答える
1

Integer[1] 配列を使用してより簡潔にすることもできますが、匿名の内部クラス内から非最終変数を直接更新できるとは思いません。

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

結果を final として宣言する必要があると思いました (ただし、その変更はコードには影響しません)。現在のスレッドは内側のスレッドが終了するまでブロックされるため、同期について心配する必要はないと思います (ただし、結果を確認するには、変数を違反させる必要があるかもしれません)。

于 2008-09-16T20:14:43.783 に答える