I want to call a method in java which blocks for some reason. I want to wait for the method for X minutes and then I want to stop that method.
I have read one solution here on StackOverflow which gave me a first quick start. I am writing that here :-
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() {
return something.blockingMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
// handle the timeout
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
future.cancel(); // may or may not desire this
}
But now my problem is, my function can throw some Exception which I have to catch and do some task accordingly. So if in code the function blockingMethod() thorws some exception how do I catch them in Outer class ?
You have everything set up to do that in the code you provide. Just replace
// handle other exceptions
with your exception handling.
If you need to get your specific Exception you get it with:
Throwable t = e.getCause();
And to differentiate between your Exceptions you can do like this:
if (t instanceof MyException1) {
...
} else if (t instanceof MyException2) {
...
...
In cause of ExecutionException instance, I suppose.
In the ExecutionException catch block: e.getCause()
https://docs.oracle.com/javase/6/docs/api/java/lang/Throwable.html#getCause
thread.sleep(x millisecods) will stop the thread for x milliseconds, then it will resume. The other way to do it is to call thread.wait(x) (with a timeout value for x) and then call thread.notify() to "wake" the sleeping thread.
Related
I've learnt that it is the good practice to set Thread.interrupter() flag back to true after catching a InterruptedException.
However when I call executorService.invokeAll() and put a try clause around it, by catching the InterruptedException, will Thread.currentThread().interrupt() correctly flag the interrupted thread, or the main thread of my controller/runner?
public class Controller {
public void run() {
final List<Task> tasks = request.collectTasks()
try {
executorService.invokeAll(tasks);
} catch (InterruptedException e) {
message = "interrupted";
Thread.currentThread().interrupt();
throw new InternalFailureException(message);
}
}
}
class Task implements Callable<String> {
#Override
public String call() {
return taskId;
}
}
Overall is this the correct way to reset the interrupted flag?
In this code example you have given
try {
executorService.invokeAll(tasks);
} catch (InterruptedException e) {
message = "interrupted";
Thread.currentThread().interrupt();
throw new InternalFailureException(message);
}
whoever invokes Thread.currentThread().interrupt(); will set the flag of that thread in this example it will be the thread executing your Controller#run() method.
Ideally with executors it is the responsibility of Task or Runnable which gets scheduled over the executor to handle this flag properly.
Since it is a checked exception already - it will not give you an opportunity to decorate the task that you are about to submit inside executor so you have no easy control over it.
I've got my own class that implements com.ibm.websphere.asynchbeans.Work with the following run method:
#Override
public void run() {
try {
agentManager.loadLibContent(agent);
} catch (Exception e) {
ErrorAnalizer.report(e);
log.error("some err: "+e.getMessage());
//this.setStatus("error");
//throw new RuntimeException(e);
} finally {
workLoadManager.delRunTask(getTaskHistory());
}
}
This work-class is passed to startWork(Work var1) method of com.ibm.websphere.asynchbeans.WorkManager.
When I get an exception in the try block it is being caught and logged, no problem.
But I want that exception to go upper till it reaches the very first method that called websphere's startWork.
How to do that? Runnable does not let to throw checked exception. RuntimeException didn't help. It seems startWork swallows it somewhere inside.
Bad thing that this first method is located in another project module and I can not reach it from catch block to pass info to do some job.
I also tried to setStatus in my work-class and then get it after but looks like startWork don't let me to change passed object.
Any help is appreciated. Thank you!
You need to use the WorkItem.getResult method:
MyWork myWork = ...
WorkItem wi = wm.startWork(myWork);
...
try {
myWork = (MyWork)wi.getResult();
...
} catch (WorkException e) {
Throwable cause = e.getCause();
...
}
Then, there are two options:
The catch block in your run method can store the exception in an instance field, and then you can retrieve it after calling getResult.
The run method throws an unchecked exception, and it should be available as the cause of the WorkException that is caught.
To get the result of submitted asynchbeans Work, you can store a reference to the com.ibm.websphere.asynchbeans.WorkItem and invoke getResult() which will return the result of your work if it completed successfully, or it will throw a com.ibm.websphere.asynchbeans.WorkException which wraps the exception thrown by the Work implementation.
Here is an example:
// Submit the work
WorkItem workItem = workManager.startWork(new MyWork());
// Wait for the work to be done for up to 60s
ArrayList<WorkItem> items = new ArrayList<WorkItem>();
boolean workFinished = workManager.join(items, WorkManager.JOIN_AND, 60*1000);
if(workFinished)
try {
MyWork work = workItem.getResult();
// if we get here, the work completed without errors
} catch(WorkException e) {
throw e.getCause(); // this will be the exception thrown by your Work impl
}
else {
// the Work did not finish in 60s
}
I am implementing an interface which throws IOException. In my implementation, I call another method which can block, and therefore throw InterruptedException.
Context:
I want to end the treatment if I am interrupted;
this is not a thread I created myself.
My current idea is to do as such (skeleton code):
#Override
public void implementedMethod()
throws IOException
{
try {
methodThatBlocks();
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
throw new IOException();
}
}
is that the correct way? Or should I just throw and not .interrupt()?
Yes, you should call interrupt() to let the calling code know that the thread has been interrupted. If you don't do it, since the InterruptedException clears it, the calling code will have no way to know about the interruption and won't stop running although it should.
Let me quote Java Concurrency in Practice:
Restore the interrupt. Sometimes you cannot throw InterruptedException, for instance when your code is part of a Runnable. In these situations, you must catch InterruptedException and restore the interrupted status by calling interrupt on the current thread, so that code higher up the call stack can see that an interrupt was issued,
as demonstrated in Listing 5.10.
public class TaskRunnable implements Runnable {
BlockingQueue<Task> queue;
...
public void run() {
try {
processTask(queue.take());
} catch (InterruptedException e) {
// restore interrupted status
Thread.currentThread().interrupt();
}
}
}
Of course not. The thread is already unblocked and running. In the code that is about to throw an exception. What would be the point?
I'm using ExecutorService, Future and Callable to do parallel processing. Though the Callable's exception can be caught when invoking Future#get, how to catch all the exceptions thrown by all callables and then throw a huge, compound exception, like:
ExecutorService service = Executors.newFixedThreadPool(5);
List<Future<Void>> futures = new ArrayList<Future<Void>>();
futures.add(service.submit(new TaskA());
futures.add(service.submit(new TaskB());
for (Future<Void> future : futures) {
try {
future.get();
} catch (Exception e) {
// ???
}
}
// throw the big exception here
service.shutdown();
If you want to associate multiple exceptions with a single throw, use addSuppressed on your outermost exception.
It won't help you much on the catch side, but comprehensive error handling is never easy, especially after joining multiple threads of control.
Maybe I'm missing something, but
public class CompositeException extends Exception {
private List<Exception> exceptions = new ArrayList<Exception>();
public List<Exception> getExceptions() {
return exceptions;
}
}
Instantiate one of these puppies and load it up with all the exceptions before throwing it.
Hey, I'm writing a network application, in which I read packets of some custom binary format. And I'm starting a background thread to wait for incoming data. The problem is, that the compiler doesn't let me to put any code throwing (checked) exceptions into run(). It says:
run() in (...).Listener cannot implement run() in java.lang.Runnable; overridden method does not throw java.io.IOException
I want the exception to kill the thread, and let it be caught somewhere in the parent thread. Is this possible to achieve or do I have to handle every exception inside the thread?
To be able to send the exception to the parent thread, you can put your background thread in a Callable (it allows throwing also checked exceptions) which you then pass to the submit method of some Executor. The submit method will return a Future which you can then use to get the exception (its get method will throw an ExecutionException which contains the original exception).
Caveat: this may not meet your needs if you have to use the exception mechanism.
If I understand you correctly, you don't actually need the exception to be checked (you've accepted the answer suggesting an unchecked exception) so would a simple listener pattern be more appropriate?
The listener could live in the parent thread, and when you've caught the checked exception in the child thread, you could simply notify the listener.
This means that you have a way of exposing that this will happen (through public methods), and will be able to pass more information than an exception will allow. But it does mean there will be a coupling (albeit a loose one) between the parent and the child thread. It would depend in your specific situation whether this would have a benefit over wrapping the checked exception with an unchecked one.
Here's a simple example (some code borrowed from another answer):
public class ThingRunnable implements Runnable {
private SomeListenerType listener;
// assign listener somewhere
public void run() {
try {
while(iHaveMorePackets()) {
doStuffWithPacket();
}
} catch(Exception e) {
listener.notifyThatDarnedExceptionHappened(...);
}
}
}
The coupling comes from an object in the parent thread having to be of type SomeListenerType.
This answer is based on Esko Luontola one but it provides a working example.
Unlike the run() method of the Runnable interface the call() method of Callable allows to throw some exceptions. Here is an implementation example :
public class MyTask implements Callable<Integer> {
private int numerator;
private int denominator;
public MyTask(int n, int d) {
this.numerator = n;
this.denominator = d;
}
#Override
// The call method may throw an exception
public Integer call() throws Exception {
Thread.sleep(1000);
if (denominator == 0) {
throw new Exception("cannot devide by zero");
} else {
return numerator / denominator;
}
}
}
Executor provides a mechanism to run a Callable inside a thread and to handle any kind of exceptions :
public class Main {
public static void main(String[] args) {
// Build a task and an executor
MyTask task = new MyTask(2, 0);
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
try {
// Start task on another thread
Future<Integer> futureResult = threadExecutor.submit(task);
// While task is running you can do asynchronous operations
System.out.println("Something that doesn't need the tasks result");
// Now wait until the result is available
int result = futureResult.get();
System.out.println("The result is " + result);
} catch (ExecutionException e) {
// Handle the exception thrown by the child thread
if (e.getMessage().contains("cannot devide by zero"))
System.out.println("error in child thread caused by zero division");
} catch (InterruptedException e) {
// This exception is thrown if the child thread is interrupted.
e.printStackTrace();
}
}
}
What I do is to catch the exception in the thread and store it as a member variable of the Runnable. This exception is then exposed via a getter on the Runnable. I then scan all the threads from the parent to see if any had exceptions, and take the appropriate action.
If you really cannot do anything useful when the exception is raised you can wrap the checked exception in a RuntimeException.
try {
// stuff
} catch (CheckedException yourCheckedException) {
throw new RuntimeException("Something to explain what is happening", yourCheckedException);
}
the thread can't throw the exception to any other thread (nor to the main thread). and you cannot make the inherited run() method throw any checked exceptions since you can only throw less than the inherited code, not more.
If your thread's code throw a RuntimeExpection, you doesn't need to add run() throw Exception.
But use this solution only when appropriate because this can be a bad pratice:
http://java.sun.com/docs/books/tutorial/essential/exceptions/runtime.html
Any RuntimeException or unchecked Exception can help you. Maybe you'll need to create your own RuntimeException
On the assumption that your code is in some kind of loop, you'd write:
public class ThingRunnable implements Runnable {
public void run() {
try {
while(iHaveMorePackets()) {
doStuffWithPacket()
}
} catch(Exception e) {
System.out.println("Runnable terminating with exception" + e );
}
}
}
The exception will automatically break you out of your loop, and at the end of the run() method, the thread will stop.
Use this Runnable to create your Thread:
public abstract class TryRunner implements Runnable{
protected abstract void tryToRun();
protected void onException(Exception e){}
#Override
final public void run() {
try{ tryToRun(); }catch(Exception e){ e.printStackTrace(); onException(e); }
}
}
Wrapping your exception inside a RuntimeException seems to do the trick.
someMethod() throws IOException
{
try
{
new Thread(() ->
{
try
{
throw new IOException("a checked exception thrown from within a running thread");
}
catch(IOException ex)
{
throw new RuntimeException("a wrapper exception", ex); // wrap the checked exception inside an unchecked exception and throw it
}
}).start();
}
catch(RuntimeException ex) // catch the wrapped exception sent from within the thread
{
if(ex.getCause() instanceof IOException)
throw ex.getCause; // unwrap the checked exception using getCause method and use it however you need
else
throw ex;
}
}