如何在Java中克隆异常

如何在Java中克隆异常,java,multithreading,exception,synchronization,semaphore,Java,Multithreading,Exception,Synchronization,Semaphore,我有一个数据更新程序线程,它使用回调将结果或异常返回给管理器。我使用信号量来同步管理器启动并获取后台线程工作的结果(结果或异常)。只有其他线程通过调用使用同步器.tryAcquire()的runUpdate来启动管理器。其他线程可以随时尝试从管理器获取结果。所以当这种情况发生时,我通过检查信号量状态来检查后台线程是否完成了它的工作。所以为了返回一个结果,我用构造函数克隆它,然后释放信号量。但在例外情况下,我不能这样做。我必须创建一个新的异常,从而丢失它的实际类和堆栈跟踪,或者在抛出异常之前释放信

我有一个数据更新程序线程,它使用回调将结果或异常返回给管理器。我使用信号量来同步管理器启动并获取后台线程工作的结果(结果或异常)。只有其他线程通过调用使用同步器.tryAcquire()的
runUpdate
来启动管理器。其他线程可以随时尝试从管理器获取结果。所以当这种情况发生时,我通过检查信号量状态来检查后台线程是否完成了它的工作。所以为了返回一个结果,我用构造函数克隆它,然后释放信号量。但在例外情况下,我不能这样做。我必须创建一个新的异常,从而丢失它的实际类和堆栈跟踪,或者在抛出异常之前释放信号量,并冒得到错误结果的风险(
getReturnedException()
可能已经返回null或其他异常)

private final信号量同步器=新信号量(1,true);
public List getResult()引发异常{
if(synchronizer.tryAcquire(1,TimeUnit.ms)){
if(getReturnedException()==null){
List tempResult=新建ArrayList(结果);
同步器释放();
返回结果;
}否则{
Exception clonedEx=cloneException(getReturnedException());//克隆异常的某种方法
投掷克洛奈德;
}
}否则{
抛出新异常(“后台线程仍在工作”);
}
}
公共void processException(异常ex,线程){
setReturnedException(ex);
同步器释放();
}

那么有没有一种方法可以实现
cloneException
功能?

您可以在不进行任何克隆的情况下完成这项功能,还可以解决另一个问题,即如果您抛出
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();
}
Exception ex=getReturnedException();
试一试{
如果(ex==null){//你是说这里等于null吗?
List tempResult=新建ArrayList(结果);
返回结果;
}否则{
掷骰子;
}
}最后{
同步器释放();
}

您不需要克隆异常。您只需要在
finally
块中释放资源,这样它就会一直发生。

您可以在不进行克隆的情况下抛出它:)此外,您的getReturnedException在else分支中为null。你确定吗?是的,我犯了个错误。编辑了这篇文章。是的,我的意思是ex==null。编辑了这篇文章。我确实知道这个构造是如何工作的(尝试{return false;}最后{return true;}将返回true)。但我不确定抛出异常时是否也是这样。根据官方Java文档:“当try块退出时,finally块总是执行”。因此答案是肯定的,无论抛出异常还是出现正常的
return
语句,
finally
都会被调用。@music\u coder:总是,除非try/catch有一个System.exit调用,或者发生了一些非常糟糕的事情(例如:JVM错误),因为此时整个程序都死了,你能做的不多:)我在这里编写的这个方法为你准备了几乎每一个“可处理”的情况。
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();
}