1

数回見たが、それが正しいかどうかまだわからないパターン:Display.syncExecを介してSWTUIスレッドでコードを呼び出す必要があります。UIスレッドで実行されるコードは、チェックされた例外をキャッチし、この例外を待機中のスレッドに伝播したいと考えています。パターンは次のようになります。

SomeCheckedException[] exc = new SomeCheckedException[] { null };
display.syncExec(new Runnable(){
   public void run(){
      try {
         new Work().something();
      } catch (SomeCheckedException e){
         exc[0] = e;
      }
   }
});

if (exc[0] != null){
 //..
}

ここに実際の同時実行性がない場合でも、これは可視性の観点からは実際には安全ではないと思います。UIスレッドが例外を格納する可能性は十分にありますが、呼び出し元のスレッドはこれを認識せず、「null」を読み取ります。再び制御を取得した後、アレイにアクセスします。私は正しいですか?SWTExceptionをキャッチし、そのスロー可能なフィールドをチェックするのが最善の方法instanceofですか?編集:うーん、それがチェックされた例外である場合、それはそれほど簡単には機能しません。自分でcatchブロックからSWTExceptionをスローする必要があります。より良い解決策?

あなたの助けとコメントをありがとう。

4

2 に答える 2

1

これは、 AtomicReferenceが作成された種類のケースです。

  void foo() throws SomeCheckedException {
    final AtomicReference<SomeCheckedException> exRef = new AtomicReference<>();
    display.syncExec(new Runnable() {
      public void run() {
        try {
          new Work().something();
        } catch (SomeCheckedException e) {
          exRef.set(e);
        }
      }
    });
    SomeCheckedException ex = exRef.get();
    if (ex != null) {
      throw ex;
    }
  }
于 2012-08-14T12:01:14.263 に答える
0

UIスレッドはメインスレッドとは異なるスレッドであるため、ここには実際の同時実行性があります。これにより、exc[0]がnullになることは間違いありません。

UIスレッドがいっぱいになるまでメインスレッドを待機させたい場合は、配列へのアクセスを同期する必要があります。そして、あなたもそれを計る必要があります。おそらく、メインスレッドは、いっぱいになるまで何度もチェックする必要があります。または、サスペンド(スリープ)して、UIスレッドにウェイクアップ(通知)させることもできます。

編集:待機中のスレッドの解決策は、通知なしで、単に数ミリ秒スリープしてからチェックします。

//object properties
volatile Exception e = null;
volatile Exception completed = false;
...
display.syncExec(new Runnable(){
    public void run(){
        try
        {
          ...
          e = thrownException;
          ....
        } catch (...){};
        //must be after the try block:
        completed = true;
    }
...
while(! completed)
    Thread.sleep(500) //or something, lookup the javadoc
//after the while ends, you can safely access e
于 2012-08-14T11:46:01.223 に答える