¿Cómo puedo clonar una excepción en Java?
Frecuentes
Visto 1,834 veces
2
I have a data updater thread that uses callbacks to return either result or an exception to a manager. I use semaphore to synchronize manager start and getting the results of a background thread's work (either result or a an exception). Manager is launched only by other threads by calling runUpdate
que los usos synchronizer.tryAcquire()
. Other threads can try to get result from a manager at any time. So when that happens I check if background thread finished it's work by checking semaphore state. So to return a result I clone it by a constructor and than I release semaphore. But in a case of exception I cannot do this. I must either create a new Exception thus losing it's actual class and stack trace or release semaphore before throwing an exception and risk getting incorrect results (getReturnedException()
can already return null or other exception).
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();
}
So is there a way to implement cloneException
¿función?
2 Respuestas
1
You might be able to accomplish this without any cloning, as well as solve another problem, which is that you're currently not releasing synchronizer
si tiras clonedEx
. Prueba esto en su lugar:
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();
}
respondido 27 nov., 13:06
Yes I meant ex == null. Edited the post. I do know how this construction works (try { return false; } finally { return true; } will return true). But I'm not sure if this is the same when throwing an exception. - DeGriz
Per the official Java docs: "The finally block siempre executes when the try block exits". So the answer is yes, the finally
is called whether an exception is thrown or your normal return
statement occurs. - codificador_musical
@musical_coder: Always, except when try/catch has a System.exit call or something really bad happens(Example : JVM error) - Silviu Burcea
Seeing as your whole program is dead at that point, there ain't much you can do :) This approach I coded here prepares you for just about every "handleable" situation. - codificador_musical
0
You don't need to clone the exception. You just need to release your resource in a finally
block, so that it always happens.
respondido 27 nov., 13:06
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas java multithreading exception synchronization semaphore or haz tu propia pregunta.
You can throw it without cloning :) Also, your getReturnedException is null in the else branch. Are you sure? - Silviu Burcea
Yeah, I made a mistake. Edited the post. - DeGriz