using a timer to destroy/interupt a process in Java - java

Hi I am wondering how I could use a timer to destroy a process if it elapses a predefined time period in milisecs.
Currently I have a method which gets the thread from runtime
Runtime runtime = Runtime.getRuntime();
I then create separate process to execute a command using the runtime
Process process = runtime.exec(comman); //where command is a string with a defined command
I then handle the normal/error output streams before calling:
process.waitFor();
this waits for the process to terminate if it hasn't already.
My question is, how can I go about using a timer to terminate the process before it has finished, i.e. by calling:
process.destroy;
Basically, if the process works for more than a certain length of time, I want to destroy it prematurely.
I would then throw an InterruptedException if it was destroyed because of over runing.
I was told that using a timer would be the best way to achieve this, but wasnt sure if this was the case?
Any help would be hugely appreciated.

try
final Process p = ...
final Thread mainThread = Thread.currentThread();
Thread t = new Thread() {
public void run() {
try {
Thread.sleep(1000);
p.destroy();
mainThread.interrupt();
} catch (InterruptedException e) {
}
};
};
p.waitFor();
if (mainThread.isInterrupted()) {
throw new InterruptedException();
}
t.interrupt();

Related

Scenario's where a Java thread running in infinite loop for a long run be terminated by JVM

I have a Runnable thread which loops through an infinite loop. Per iteration it sleeps upto next task time and then does some task. This task is very critical hence makes the thread running it also very critical. I am not really a java thread expert so I was wondering what can be the various scenarios or possibilities where the JVM may decide to stop / terminate this thread. At the application level there is no restriction for number of running threads or so. I am concerned about how JVM would behave for a long-run.
For now everything works fine in my local test system but I could hardly test this for some hours. This is an web application running under Apache Tomcat.
The thread creation and running is simple as shown below :
Thread taskThread = new Thread(new TaskRunnable(taskObject));
taskThread.start();
Loop :
public void run()
{
for (;;)
{
long sleepTime = this.taskObject.getNextTaskTime() - System.currentTimeMillis();
if (sleepTime > 0L) {
try
{
Thread.sleep(sleepTime);
}
catch (InterruptedException localInterruptedException)
{
localInterruptedException.printStackTrace();
}
}
this.taskObject.performTask(); // also computes next task time
}
}
Or this will work fine for a long-run as long as there are no exceptions in the running thread itself..
Java does not terminate threads on it's own unless one of three things happen:
The JVM is shut down
The thread's (or it's Runnable's) run() method exits
An uncaught exception is thrown from it's (or it's Runnable's) run() method.
This thread will stay up as long as the JVM is up or it is interrupted:
public class MyLongRunningThread extends Thread {
#Override
public void run() {
while(true) {
try {
// Do stuff
} catch(InterruptedException e) {
// The thread was interrupted, which means someone wants us to stop
System.out.println("Interrupted; exiting");
return;
} catch(RuntimeException e) {
e.printStackTrace();
}
}
}
}
Note that the only way the thread will be interrupted is if you (or some framework you're using) calls it's interrupt() method.

Need to execute a piece of code repeatedly for fixed duration in java

I have written a piece of code . How can I get that code to run for certain duration repeatedly, say for 10 second?
The ExecutorService seems to provide methods which execute tasks until they are either completed or else a timeout occurs (such as the invokeAll).
You can give a try to Quartz Job Scheduler
Quartz is a richly featured, open source job scheduling library that
can be integrated within virtually any Java application - from the
smallest stand-alone application to the largest e-commerce system.
Quartz can be used to create simple or complex schedules for executing
tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks
are defined as standard Java components that may execute virtually
anything you may program them to do. The Quartz Scheduler includes
many enterprise-class features, such as support for JTA transactions
and clustering.
If you are familiar with Cron in Linux , this will be a cakewalk for you .
Use a worker and start it in a thread, wait in the main thread for the specific time and stop the worker after this.
MyRunnable task = new MyRunnable();
Thread worker = new Thread(task);
// Start the thread, never call method run() direct
worker.start();
Thread.sleep(10*1000); //sleep 10s
if (worker.isAlive()) {
task.stopPlease(); //this method you have to implement
}
Not too sure why people downvoted the question. Be sure to in the future provide some sample code. Your answer however is simple here. Create a new thread to watch the wait. In simple code:
public class RunningClass {
public static void runThis(){
TimerThread tt = new TimerThread();
tt.timeToWait = 10000;
new Thread(tt).start();
while (!TimerThread.isTimeOver){
\\Code to execute for time period
}
}
class TimerThread implements Runnable {
int timeToWait = 0;
boolean isTimeOver = false;
#override
public void run(){
Thread.sleep(timeToWait);
}
}
The code above can be put in the same class file. Change the 10000 to whatever time you require it to run for.
You could use other options, but it would require you to have knowledge on workers and tasks.
not sure what was the exact requirement, but
if your req was to cancel only a long running task
you could use ExecutorService & Future (in jdk 5) as follows.
ExecutorService fxdThrdPl = Executors.newFixedThreadPool(2);
// actual task .. which just prints hi but after 100 mins
Callable<String> longRunningTask = new Callable<String>() {
#Override
public String call() throws Exception {
try{
TimeUnit.MINUTES.sleep(100); // long running task .......
}catch(InterruptedException ie){
System.out.println("Thread interrupted");
return "";
}
return "hii"; // result after the long running task
}
};
Future<String> taskResult = fxdThrdPl.submit(longRunningTask); // submitting the task
try {
String output = taskResult.get(***10**strong text**, TimeUnit.SECONDS***);
System.out.println(output);
} catch (InterruptedException e) {
} catch (ExecutionException e) {
} catch (TimeoutException e) {
***taskResult.cancel(true);***
}

Check exit status of main

I am invoking the main class of a .class contained in the same folder from my Java code. That main is void, and I want to check whether it was successful or not by checking its exit status:
...
String[] arguments = new String[]{"a", "b"};
AnotherClass.main(arguments);
...
Any idea on how, being that AnotherClass.main(arguments); does not return anything?
Thank you.
Even better idea -- instead of trying to call a main method, instead create a method in your other class called testMain() which does the same thing as main except it returns the exit code instead of exiting.
System.exit() called in that main method will shut down your entire program. You want to run the other main in another thread and find the exit code for that thread.
Build the other program (name the jar AnotherClass.jar), add the jar to your path and try this:
int exitCode;
try {
Process process = Runtime.getRuntime().exec("java AnotherClass.jar",new String[]{"arg1","arg2"});
exitCode = process.waitFor();
System.out.println(exitCode);
} catch (IOException e) {
System.out.println("IO Error: " + e);
} catch (InterruptedException e) {
System.out.println("Inturrupted: " + e);
}
EDIT: The following will not work at all; System.exit() kills all threads.
This code will run another main method in a new thread, and when it exits it will not harm your current program.
Thread anotherProgram = new Thread(new Runnable() {
#Override
public void run() {
AnotherClass.main(new String[]{"foo","bar"});
}
});
anotherProgram.start();
If you mean the exit code parameter to System.exit(int status), you cannot access it, as when it is called by some part of the main method (or subsequently executed code), your application is exited, and so there is nothing left running to get at the code.
The only way to check the exit code of an application is using the OS, e.g. the $? environment variable in unix tells you the exit code of the last application to terminate in that session.
Edit: Here's an example using ProcessBuilder to do so:
Process p = new ProcessBuilder(System.getProperty("java.home")+"/bin/java", "fully.qualified.package.to.AnotherClass").start();
Integer exitCode = null;
while (exitCode == null) {
try {
exitCode = p.waitFor();
} catch (InterruptedException e) {
// handle e
}
}

java create un-cooperative thread for testing

I've been bit a few times by a java process that wouldn't cooperate and exit cleanly (it would be buried in some low-level libraries out of my control). I am now testing a sort of watchdog that implements a hard stop for the process at some pre-established time, ScheduledStop. That watchdog is a singleton class that runs an independent thread that will kill the whole process if the scheduled stop time arrives. Normally, all threads should return nicely before that hard-stop time and the program exits gracefully. If necessary however, the process kills itself, file locks are released etc. All of this runs on Linux.
I seem to remember that even System.exit(0) is not fool-proof (I think if some shutdown hooks are getting stuck, the process may stay alive), so I have concocted something along the line of:
int pid = MyUtil.getPID();
Runtime.getRuntime().exec(new String[]{"kill", "-9", String.valueOf(pid)});
Now, I'd like to test it with some really un-cooperative threads, and possibly some shutdown hooks that, on purpose for the test, are not doing well.
The itinial NastyThread below is not all that nasty... It ignores InterruptionException, but doesn't prevent System.exit(0). How can I put my VM into a state that even exit() doesn't terminate?
Another question is, although the watchdog thread is in theory independent, what are the conditions where other threads would completely preempt it, thus foiling the scheduled stop?
If necessary, I could launch a separate process (e.g. a simple perl script) that kills the parent (the java process) at some specified time.
/**
* A Runnable that runs forever and ignores InterruptedException.
*/
private static class NastyThread implements Runnable {
#Override
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("Received and ignoring "+e);
System.out.flush();
}
System.out.println(ScheduledStop.getInstance().toString());
}
}
}
You can set a SecurityManager to ignore or throw an Error when System.exit() is called.
BTW
while(true) Thread.yield();
or
for(;;);
will ignore interrupts as well.
Ok, I added a SecurityManager as suggested by #Lawrey. Somehow the application can still happily System.exit(0).
But then, I added a shutdown hook that just launches one more nasty thread! That does the trick, and now my ScheduledStop class can be tested (and works). Here is the shutdown hook:
Runtime.getRuntime().addShutdownHook(new Thread(
new NastyThread("nasty-1 (shutdown-hook)")
));
Here is the output of the test:
gp> ~$ java -cp "$CLASSPATH" com.somepackage.ScheduledStop
nasty-0: Stop scheduled at 20130916-111611-PDT (in PT4.488S)
nasty-0: Stop scheduled at 20130916-111611-PDT (in PT3.939S)
nasty-0: Stop scheduled at 20130916-111611-PDT (in PT3.437S)
main would like to exit(0).
nasty-0: Stop scheduled at 20130916-111611-PDT (in PT2.936S)
nasty-1 (shutdown-hook): Stop scheduled at 20130916-111611-PDT (in PT2.487S)
nasty-0: Stop scheduled at 20130916-111611-PDT (in PT2.434S)
nasty-1 (shutdown-hook): Stop scheduled at 20130916-111611-PDT (in PT1.985S)
nasty-0: Stop scheduled at 20130916-111611-PDT (in PT1.932S)
nasty-1 (shutdown-hook): Stop scheduled at 20130916-111611-PDT (in PT1.484S)
nasty-0: Stop scheduled at 20130916-111611-PDT (in PT1.431S)
nasty-1 (shutdown-hook): Stop scheduled at 20130916-111611-PDT (in PT0.981S)
nasty-0: Stop scheduled at 20130916-111611-PDT (in PT0.928S)
nasty-1 (shutdown-hook): Stop scheduled at 20130916-111611-PDT (in PT0.479S)
nasty-0: Stop scheduled at 20130916-111611-PDT (in PT0.426S)
Hard stop (kill -9 self=6967).
zsh: killed java -cp "$CLASSPATH" com.somepackage.ScheduledStop
FWIW, here is the whole "test" code (not a real test, just taking ScheduledStop for a little drive around the block):
/*----------------------------------
* all the code below is for testing
*/
/**
* A Runnable that runs forever and ignores InterruptedException.
*/
private static class NastyThread implements Runnable {
private final String name;
public NastyThread(String name) {
super();
this.name = name;
}
#Override
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(name+": received and ignoring "+e);
System.out.flush();
}
System.out.println(name+": "+ScheduledStop.getInstance().toString());
}
}
}
#SuppressWarnings("serial")
private static class ExitTrappedException extends SecurityException { }
private static void forbidSystemExitCall() {
final SecurityManager securityManager = new SecurityManager() {
public void checkPermission(Permission permission ) {
if ("exitVM".equals(permission.getName())) {
throw new ExitTrappedException() ;
}
}
};
try {
System.setSecurityManager(securityManager);
} catch (Exception e) {
System.err.println("got: "+e);
}
}
#SuppressWarnings("unused")
private static void enableSystemExitCall() {
System.setSecurityManager( null ) ;
}
/**
* Spawn an un-cooperative thread, then kill itself after a few seconds.
*/
public static void main(String[] args) throws IOException {
final File lockFile = new File("testStop.lock");
final Period runFor = Period.seconds(5);
try (HplFileLock lock = FileUtil.getFileLockOrExit(lockFile, 0)) {
ScheduledStop.getInstance().runFor(runFor);
} catch (Exception e) {
System.err.println("Exception: " + e);
System.err.flush();
System.exit(-1);
}
// disallow System.exit()
forbidSystemExitCall();
// launch a pesky thread that ignores interruption
Runnable r = new NastyThread("nasty-0");
new Thread(r).start();
// further, install a shutdown hook that just launches one more NastyThread!
Runtime.getRuntime().addShutdownHook(new Thread(new NastyThread("nasty-1 (shutdown-hook)")));
// now wait 2 seconds and try to exit
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main would like to exit(0).");
System.out.flush();
System.exit(0);
}

HowTo- thread stop

just a little question, i want to stiop the following thread, but i have no idea how i should do. Please help me. Googles help wasnt useful this time.
new Thread(){
public void run() {
while(!isInterrupted()){
try {
if (sock1!=null){
sock1.setTcpNoDelay(true);
if (btsar1.length > 0) {
dos1 = new DataOutputStream(sock1.getOutputStream());
bwrtr1 = new BufferedWriter(new OutputStreamWriter(
dos1), 300);
dos1.write(btsar1);
set1free = false;
Log.e("Communication", "written(1.1)");
Reader1.reader(4);}
}} catch (IOException e) {
e.printStackTrace();
}catch (NullPointerException e2){
e2.printStackTrace();
}
}
}}.start();
//.interrupt(); <-- or kinda that...
Can someone provide a good working thing, to stop this?
You just need a reference to your thread:
Thread t = new Thread(...);
Then you can interrupt it:
t.interrupt();
Thread t = new Thread(){
... // content unchanged
};
t.start();
.....
t.interrupt();
The best way to terminate a thread is to let it finish. So add a boolean flag in your while, and have method (or otherwise) expose it so it can be set to false. Then your thread would naturally exit after the interation has finished.
An idea: stop using anonymous threads!
Whenever you find yourself in a situation where your thread is doing something complicated, either create a separate class extending the thread, which can be used to control and monitor the behaviour, or use an abstract Future and a ThreadPool to do the work.
You will have an extremely unmaintainable and unextendable code if you keep using threads like this.
How to stop a thread gracefully?
bool keepWorking = true;
while(keepWorking) {
// keep working
}
synchronized void stopWork() {
keepWorking = false;
}
// in other thread
threadObj.stopWork();
Thread.interrupt method is for to stop a thread that waits for long periods (e.g., for input)
Take a look at this Article - How to Stop a Thread or a Task
example
public void stop() {
Thread moribund = waiter;
waiter = null;
moribund.interrupt();
}

Categories