Java 将Display.syncExec期间捕获的异常传播到调用线程

Java 将Display.syncExec期间捕获的异常传播到调用线程,java,concurrency,swt,Java,Concurrency,Swt,我已经见过几次了,但仍然不确定它是否正确:我需要通过Display.syncExec调用SWT UI线程上的一些代码。在UI线程中运行的代码捕获已检查的异常,并希望将该异常传播到等待的线程。模式如下所示: SomeCheckedException[] exc = new SomeCheckedException[] { null }; display.syncExec(new Runnable(){ public void run(){ try { new W

我已经见过几次了,但仍然不确定它是否正确:我需要通过Display.syncExec调用SWT UI线程上的一些代码。在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
检查其可丢弃字段的最佳方法是什么呢?编辑:嗯,如果它是一个选中的异常,那就不那么容易了。我需要自己把SWTException从挡块上扔下来。更好的解决方案


感谢您的帮助和评论。

这里有真正的并发性,因为UI线程与主线程不同。这肯定会导致exc[0]为空

如果希望主线程等待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

这里存在真正的并发性,因为UI线程与主线程是不同的线程。这肯定会导致exc[0]为空

如果希望主线程等待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
这类案例的目的是:

  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;
    }
  }
void foo()抛出一些CheckedException{
最终原子引用exRef=新原子引用();
display.syncExec(新的Runnable(){
公开募捐{
试一试{
新的工作某事;
}捕获(SomeCheckedException e){
exRef.set(e);
}
}
});
SomeCheckedException ex=exRef.get();
如果(ex!=null){
掷骰子;
}
}
这类案例的目的是:

  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;
    }
  }
void foo()抛出一些CheckedException{
最终原子引用exRef=新原子引用();
display.syncExec(新的Runnable(){
公开募捐{
试一试{
新的工作某事;
}捕获(SomeCheckedException e){
exRef.set(e);
}
}
});
SomeCheckedException ex=exRef.get();
如果(ex!=null){
掷骰子;
}
}
FYI:阻塞,直到任务在UI线程上执行为止;不需要while loop.FYI:在UI线程上执行任务之前阻塞;不需要while循环。