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)
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.
When i enclose Thread.wait() in a while loop my IDE (NetBeans) tells me that this may cause perfomance issues, how can it and is there a way arround it?
Example:
while (timing){
Thread.wait(10);
foo++;
}
//Started in a seperate thread before activating.
EDIT: Thanks for the help, I will try to use the 'ScheduledExecutorService' instead!
You probably wanted to just make the thread sleep, and that is the name of the method you needed to call.
You called Object#wait(), which is a thread coordination method, and you used an explicit timeout on it (a rather short one). My guess is that NetBeans is warning you about that timeout because normally we use Object#wait without a timeout, and if we use the timeout, we don't wait in a loop.
Now, NetBeans will also warn you about using Thread.sleep() in a loop because normally, if you want to schedule a repeated task (that is what you are doing), you will use a ScheduledExecutorService. That service is able to serve a lot of different scheduled tasks around your application, all with a single thread. Writing Thread.sleep() explicitly in a loop needlessly hogs a whole thread (a heavyweight system resource) to do nothing but sleep most of the time.
I am using a ScheduledThreadPoolExecutor which runs a ScheduledFuture every x (currently 100) msec . The task takes just a couple of msec to execute.
Trying to cancel it and interrupt possibly running tasks, by calling future.cancel(true), I observe that although the future shall terminate, the task is still executed, causing program errors. From my log output it seems that the cancelling takes place during the last execution, but cancelling it does NOT interrupt the Thread, instead it is allowed to run till its end. Also this last execution takes several times longer than the previous ones. This behaviour is reproducible but does not happen always.
To my knowledge cancelling shall immediately call interrupt() in my thread, giving me the option to react accordingly?? The weird thing is that if I artificially extend the task duration by sleeping some time at the end of run(), the interruption happens as I expected.
Does anyone have an explanation for this behaviour? Since it seems to be depending on the task duration I thought about maybe there is some weird heuristic implemented in the executor service to plan the execution schedule which is going wrong. Is there any other (smarter) way the handle the problem?
To my knowledge cancelling shall immediately call interrupt() in my thread, giving me the option to react accordingly?? The weird thing is that if I artificially extend the task runtime by sleeping some time at the end of run(), the interruption happens as I expected.
If you interrupt a thread, it basically sets a flag. If you don't check this flag, or call something which does, nothing happens as you have seen. Thread.sleep() does check, but you can check yourself with Thread.currentThread().isInterrupted();
Is there any other (smarter) way the handle the problem?
Write your code so the task checks whether it should still do something. I wouldn't rely on interrupt alone to do this. BTW Some third party libraries incorrectly consume an interrupt or handle them in ways you might not expect.
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 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.