我有一个数据更新程序线程,它使用回调将结果或异常返回给管理器。我使用信号量来同步管理器启动和获取后台线程的工作结果(结果或异常)。通过调用使用runUpdate
的{{1}},Manager仅由其他线程启动。其他线程可以随时尝试从经理那里获得结果。所以,当发生这种情况时,我会检查后台线程是否通过检查信号量状态来完成它的工作。因此,为了返回结果,我通过构造函数克隆它,而不是释放信号量。但在例外的情况下我不能这样做。我必须创建一个新的Exception,从而在抛出异常之前丢失它的实际类和堆栈跟踪或释放信号量,并冒险获得不正确的结果(synchronizer.tryAcquire()
已经可以返回null或其他异常)。
getReturnedException()
那么有没有办法实现private final Semaphore synchronizer = new Semaphore(1, true);
public List<Map<String, Object>> getResult() throws Exception {
if (synchronizer.tryAcquire(1, TimeUnit.MILLISECONDS)) {
if (getReturnedException() == null) {
List<Map<String, Object>> tempResult = new ArrayList<>(result);
synchronizer.release();
return tempResult;
} else {
Exception clonedEx = cloneException(getReturnedException()); //some way to clone an exception
throw clonedEx;
}
} else {
throw new Exception("Background thread is still working");
}
}
public void processException(Exception ex, Thread thread) {
setReturnedException(ex);
synchronizer.release();
}
函数?
答案 0 :(得分:1)
您可以在没有任何克隆的情况下完成此任务,并解决另一个问题,即如果您抛出synchronizer
,则目前不会发布clonedEx
。试试这个:
Exception ex = getReturnedException();
try {
if (ex == null) { //Did you mean equals null here?
List<Map<String, Object>> tempResult = new ArrayList<>(result);
return tempResult;
} else {
throw ex;
}
} finally {
synchronizer.release();
}
答案 1 :(得分:0)
您无需克隆异常。您只需要在finally
块中释放资源,以便始终发生。