I'm trying run some javascripts in java. I'm not sure if the scripts are correct and I'd like to kill the the invocation after a time period. This is how i run the scripts.
returnMethod = invocableEngine.invokeFunction("main", input);
My idea was to run something like a deamon thread, which starts second thread with a timeout. The second thread - ScriptEvaluator runs the invocable function, described above. ScriptEvaluator implements Runnable.
ScriptEvaluator se = new ScriptEvaluator(r);
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(Executors.callable(se)), timeout, TimeUnit.MILLISECONDS);
executor.shutdownNow();
Well it doesn't work. After timeout the Thread still runs.
Another requirement is that only one SkriptEvaluator thread is running.
EDIT: I've found something very interesting in shutdownNow(). When it doesn't guarantees the stopping of the Threads, is there guaranteed way to do that?
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
Thanks in advance
You can test how ScriptEvaluator() responds to Thread.interrupt(). If it's well written, then executor.shutdownNow() will work. If it's not, then there is no perfect solution.
However, assuming your javascript doesn't interact with your main code a that much, you can use Thread.stop(). If you decide to do this, then make sure you understand why not to use Thread.stop() in general.
Executor.shutdownNow() does not always work properly, perhaps you'll need Thread.stop() as the hardcore solution.
Related
How would you kill a thread in Java without manually checking Thread.currentThread().isInterrupted()?
For example, how would you kill a thread like this after a time out:
new Thread(() -> {
Result result = ExternalLibrary.performSomeReallyLongRunningTaskWithNoSideEffects();
System.out.println(result);
}).start();
We cannot modify the external library code to add isInterrupted checks everywhere
For the timeout part, if you're open to using guava, SimpleTimeLimiter is a good option.
If you're long running thread does frequent IO, it may be as simple as using an interrupt (which for SimpleTimeLimiter you just need to invoke with amInterruptible=true), because IO operations will generally check the interrupt flag and throw an InterruptedException which you'd hope the third party code will propogate or use to terminate the operation.
If you're long running method doesn't check interrupts or ignores them, and modifying it is not an option, you may be stuck with Thread.stop(), which is deprecated. If the long-running task is sufficiently isolated in it's operation, i.e. doesn't share variables with other running threads, and doesn't open any resources, it may be fine to just do that. But there is no way to be sure. I would definitely just try an interrupt first, it may just work.
Another alternative if the 3rd party code is truly opaque and unmodifiable, is convert it into it's own jar, and invoke it as an external process. That way the process can always be killed in isolation from your application.
In either the case of using Thread.stop() or a sending a kill signal to a separate process, you can execute these operations in response to the UncheckedTimeoutException thrown by SimpleTimeLimiter#callWithTimeout(...)
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 want to terminate(or abort) a task immediately when it is running, not to wait its ending. I search in JDK, the Timer class and the TimerTask class not satisfied, their cancel method is not proper for me, for the task will contiue to execute util it finish, but I want to stop it immediately.
What should I do? I serach for Spring and Quartz, but no good idea...
This is not something that is recommended to do in a multi threaded environment as it can break your code in all sorts of ways. For example imagine you are half way through changing something and suddenly your thread gets killed leaving it in a half-modified state. Because it is not recommended no easy way is provided to do it.
The correct way to do this is to use a Thread and interrupt it.
http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Inside your Thread code you can check isInterrupted() at times where it would be appropriate to abort and abort, but the abort is controlled by the running thread which is the only thing that knows when it is safe to do so.
The ScheduledExecutorService also allows you to work with a ScheduledFuture and cancel that, which then works in the same way as interrupting the thread does.
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean)
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'm currently working on a daemon that will be doing A LOT of different tasks. It's multi threaded and is being built to handle almost any kind of internal-error without crashing. Well I'm getting to the point of handling a shutdown request and I'm not sure how I should go about doing it.
I have a shutdown hook setup, and when it's called it sets a variable telling the main daemon loop to stop running. The problem is, this daemon spawns multiple threads and they can take a long time. For instance, one of these threads could be converting a document. Most of them will be quick (I'm guessing under 10 seconds), but there will be threads that can last as long as 10+ minutes.
What I'm thinking of doing right now is when a shutdown hook has been sent, do a loop for like 5 seconds on ThreadGroup.activeCount() with a 500ms (or so) Sleep (all these threads are in a ThreadGroup) and before this loop, I will send a notification to all threads telling them a shutdown request has been called. Then they will have to instantly no matter what they're doing cleanup and shutdown.
Anyone else have any suggestions? I'm interested in what a daemon like MySQL for instance does when it gets told to stop, it stops instantly. What happens if like 10 query's are running that are very slow are being called? Does it wait or does it just end them. I mean servers are really quick, so there really isn't any kind of operation that I shouldn't be able to do in less than a second. You can do A LOT in 1000ms now days.
Thanks
The java.util.concurrent package provides a number of utilities, such as ThreadPoolExecutor (along with various specialized types of other Executor implementations from the Executors class) and ThreadPoolExecutor.awaitTermination(), which you might want to look into - as they provide the same exact functionality you are looking to implement. This way you can concentrate on implementing the actual functionality of your application/tasks instead of worrying about things like thread and task scheduling.
Are your thread jobs amenable to interruption via Thread#interrupt()? Do they mostly call on functions that themselves advertise throwing InterruptedException? If so, then the aforementioned java.util.concurrent.ExecutorService#shutdownNow() is the way to go. It will interrupt any running threads and return the list of jobs that were never started.
Similarly, if you hang on to the Futures produced by ExecutorService#submit(), you can use Future#cancel(boolean) and pass true to request that a running job be interrupted.
Unless you're calling on code out of your control that swallows interrupt signals (say, by catching InterruptedException without calling Thread.currentThread().interrupt()), using the built-in cooperative interruption facility is a better choice than introducing your own flags to approximate what's already there.