I have a java application which calls a third party method, which can block indefinitely without throwing an exception.
Is it possible to wrap my method call in a timeout block (or thread, or other construct) such that I get back control after I assume the call is never returning?
The ThreadPoolExecutor should do what you need. Using the awaitTermination method:
Blocks until all tasks have completed execution after a shutdown
request, or the timeout occurs, or the current thread is interrupted,
whichever happens first.
all this multi threading is surely an answer but think if ur application is not a multi-threaded one, you can just store the timestamp of the moment you send the request and check it against the current timestamp. of course you will need a thread to keep track of the time. but all in all you can use that same thread for this purpose for as many functions calls you need. so dont go on implementing the runnable in ur classes. just make one tracker thread.
Related
I am currently running the JAR that I cannot change, and sometimes it simply gets stuck for no good reason. I have tried finding the ways to interrupt the thread, stop the thread, etceteras, but no luck.
Each solution offered was about doing the complete exit or waiting for a thread to complete.
What I want to do is to simply close the thread, exactly when the timeout completes, and carry on with the program.
What I do not want to do is use the while loop with a timeout, java.util.concurrent.Future, System.exit, and make a Thread.interrupt call.
None of these will help!
You can't forcibly stop a thread in mid-execution. The Thread.destroy() method would have done that, but it was never implemented, and its documentation explains why it would be unsafe to use even if it worked.
There are some other deprecated methods like Thread.stop() and Thread.suspend() which may actually work, but they're also unsafe to use; again, their documentation explains why.
Telling the thread that it should terminate itself, and then waiting for it to do so, is the only safe way to stop a thread.
As an workaround, you could run your task in an entirely separate process, so that you can destroy it when you want it to stop. That is safe, since processes are isolated from each other and destroying the child process can't leave the parent process in an unstable state.
Interacting with a separate process is more difficult, though, since you can't share variables between processes like you can with threads. You'd need to send messages through the process's input and output streams.
Actually, you can't really solve this!
What I mean is: even if you would manage to kill "your" thread that you used to trigger the 3rd party code - you have no way of killing threads or processes created by the code you are invoking.
If you want to be absolutely sure to kill all and anything, you might have to look into rather complex solutions like:
instead of just using a thread, you create a new process with a new JVM B
in that JVM B, you can call that library
but of course, that requires that you put additional code around; so that "your" code in JVM A can talk to "your" code in JVM B
And now you might be able to tear down that process, and all artifacts belonging to it. Maybe.
And seriously: to be really really sure that the 3rd party library didn't kick of anything that you can't stop; you might even have to run that JVM inside some kind of container (for example a docker instance). That you could tear down and be sure that everything is gone.
Long story short: I think there is no way to absolutely control the threads created in a thread. If you need that level of control, you need to look into "outsourcing" those calls.
You can use Executor for this. It allows you to submit tasks (e.g. runnable) and executes those tasks parallely. Also, once you call shutdown(), it lets you configure the timeout and kills all the workers if they are not finished by that time. An example would look like this:
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(() -> {
//logic to call the method of third party jar
});
//Other business logic
executor.awaitTermination(1, TimeUnit.MINUTES);
executor.shutdownNow();
TimeUnit is an enum, with values like SECONDS, HOURS, MINUTES etc (here's javadoc) so you can configure different time units. A couple of points:
Once shutdownNow is called, no new tasks will be accepted (i.e. you can't call execute or submit) and existing tasks will be stopped. So, we are basically waiting for a minute for tasks to be complete and if it is not complete, we are killing that task.
awaitTermination throws InterruptedException (as it interrupts the threads internally if they are not finished) so you will have to wrap it inside try-catch block.
Here's javadoc for Executor.
I've finally managed to implement Thread.interrupt() into my program instead of Thread.stop(). I am however not sure that I've done this well.
I have a class which extends Thread and declares several methods. EVERY method has been made to throw InterruptedException (Each method performs I/O intensive operations, some of which take several minutes to complete, I have therefore not used a thread-safe flag as the flag would not get checked until after the operation completed). I have also added the following code at several places within these methods to throw the exceptions:
if (this.isInterrupted()) throw new InterruptedException();
Within the run() method I execute all methods within a try/catch for InterruptedException. If caught, I execute Process.destroy() and BufferedReader.close() for my class variables.
This all works, and seems to work very well, however I have a couple of questions:
Is it correct to have more than 10 methods, all of which throw InterruptedException? Is there a better way to do this?
Is it correct to bloat the methods with checks for isInterrupted()?
At the end of the catch InterruptedException block, must I execute a 'return', or 'null' certain values to make the Thread available for GC? If I re-create the Thread it takes longer than usual to initialize.
Finally, are there any issues/enhancements related to what I've done?
Thanks in advance for your help!
Thread interruption in Java doesn't mean stopping the execution of that thread. It is not stop, it is interrupt. A thread can be interrupted when something fundamental and crucial changes, telling the thread that its execution context, its task or its enviroment changed in some significant way. A thread reaction to this message is implementation specific. It can be stop, it can be restart or any other action. A thread that doesn't handle interruptions cannot be interrupted, but its behaviour can still be altered, for example, by using a shared variable.
For example, imagine you have a number of threads, all searching through a part of a problem space for a solution. When one thread finds a solution, it can interrupt other threads, because their search for a solution is no longer relevant. A solution has already been found.
Or imagine one continuously working main thread and one network communication thread. Each time the network thread receives a messsage, it interrupts the working thread with the message. Based on what the message and the context is, the worker thread may decide what to do next. For example, if the message was "STOP", then it could stop all execution immediately. If the message was "RESET", it could start again from scratch or maybe not from scratch and reuse some previous work, based on the execution context.
Is it correct to have more than 10 methods, all of which throw
InterruptedException? Is there a better way to do this?
No, this is perfectly fine, as long as you know what you are doing. If you implement interruptions to just stop the threads, there is no need to throw InterruptedExceptions. A Thread's run() method is it's first, and the exception will not go any further the stack.
Is it correct to bloat the methods with checks for isInterrupted()?
Depending on the context. The checks would be usually added before some crucial code. Usually it is added as a first item in the loop block.
At the end of the catch InterruptedException block, must I execute a
'return', or 'null' certain values to make the Thread available for
GC? If I re-create the Thread it takes longer than usual to
initialize.
No. Once the Thread exists from the run() method, it's left at GC's mercy. Shared variables will not be GC'ed, as long as they are still referenced by other objects.
I have an application which uses a separate thread to execute a calculation performed in code from a separate library. I would like the user to able to cancel this operation as, depending on the parameters, it can take a long time.
I cannot use a stopping variable or check for interrupts as the calculation from the applications point of view is a single line
public void run() {
result = library.performCalculation(params);
}
I would like to be able to use thread.stop() but as far as I'm aware this is not posible on android.
Is there anyway I can cause the thread to stop running?
You're correct, Thread.stop() is not available on Android (and even on systems where it is still supported, its problems outweight its usefulness).
What you can do is two-fold. First, call thread.interrupt() to set an interrupted flag on the thread running your library. Second, modify your library at appropriate point(s) to call isInterrupted() to determine if it is interrupted and, if so, it should voluntarily clean up and leave.
An AsyncTask can be Cancelled. Put that into an AsyncTask and call
AsyncTask.cancel(true);
I'm trying to implement a sort of interrupt process into my java program so that if an operation takes longer than 5 minutes, i can kill it.
Is there any sort of generic way I can do this? I'm using an external API to carry out very processor intensive calculations and it already multithreads the process so can I still use the executor class to do this?
-edit-
Ended up solving it by using a bash script wrapper function. It kills the PID after a timeout.
It's considered unsafe to kill or forcefully stop a Thread because it may leave the program in an undetermined state, which will later cause a crash or other more serious problem. Instead, you should design your worker thread to periodically check the interrupt flag via Thread#isInterrupted or Thread#interrupted and exit if it is set. Then, using another thread, you can signal to the worker thread that it should stop by calling interrupt() on the worker thread, which will result in the worker thread detecting the interrupt or possibly receiving an InterruptedException if it is blocking inside your code or the third party code.
Depending on how your thread is coded (ie. whether it would properly terminate when interrupted), you could use the provided Thread.join(millis) or Thread.join(mills, nanos) method calls.
Something like this:
Thread myThread
// ... start myThread
myThread.join(300000); // 5mins in millis
if (myThread.isAlive()) {
myThread.interrupt();
}
Inside the thread itself, you would want to ensure that you .yield() at relevant points and properly handle an InterruptedException to allow this kind of logic to work.
Of course this is an "ideal" kinda situation - if the thread is blocked due to some outside process, and cannot handle the .interrupt(), then it will not work very well.
HTH
I want to know how to stop a specified function's execution within a specified time in java.
For example: I may call a function called print_data(). If it takes more time to execute, I will have to stop that function's execution.
Is it possible to stop the execution like this?
Thanks in advance
You could add some checks to your function: save the timestamp when function started working and then periodically checking that inside the function, throwing an exception if function takes too long.
This is the cleanest way to accomplish such task in Java.
There is no safe way to stop a thread executing, unless it is being cooperative; e.g. it regularly checks the 'interrupted' flag.
#BobbyShaftoe suggests this in a comment:
You could execute this function in a separate thread and then abort the thread after some period of time.
This is misleading and dangerous advice. The only way to "abort" a thread is to use the deprecated Thread.stop() method. If you look at the javadoc for that method you will see that it is a fundamentally dangerous method that is liable to have undesirable and unpredictable side-effects.
It should also be noted that #tonio's solution doesn't stop the function's execution. It simply stops waiting for the function's execution to finish. The function could continue executing indefinitely, chewing up resources to no good effect.
You can use the TimeUnit enum from java.util.concurrent, in particular the timedJoin method.
You specify a time to wait, and a thread. timedJoin will let your thread execute until termination, or stop if the processing takes more time than the timeout allowed. You can use an anonymous class to wrap your method in a Thread object easily.
This can be as easy as:
SECONDS.timedJoin(
new Thread() {
public void run() {
print_data();
}
},
10);
for a 10 seconds timeout.