Java 将Display.syncExec期间捕获的异常传播到调用线程
我已经见过几次了,但仍然不确定它是否正确:我需要通过Display.syncExec调用SWT UI线程上的一些代码。在UI线程中运行的代码捕获已检查的异常,并希望将该异常传播到等待的线程。模式如下所示: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
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循环。