0

I want to have mechanism by which expected process shouldn't run more than specific time. After specific time is over, status whether process is running or not should be displayed and process should no longer run.

For that I tried to make two classes Execute and Check, Execute object's run method will execute process. Check object will sleep for specific time, after which it checks whether object of Execute is still running. If it is running Check object is expected to kill that thread and print "yes". Else, Check object should print "no".

 class Execute extends Thread{
        public void run(){
            //Execute process
        }
        public static void main(String[] args){
            Execute ex = new Execute();
            ex.start();
            Check ch = new Check(ex);
            ch.start();
        }
    }
    class Check extends Thread{
        Execute ex;
        Check(Execute ex){
            this.ex = ex;
        }
        public void run(){
            try{Thread.sleep(5000);} //specific time given is 5 seconds.
            catch(Exception e){System.out.println(e);}
            if(ex.isAlive()){
            System.out.println("yes");
            //kill the thread ex.
            }
            else System.out.println("no");
        }
    }

My questions are:

  • How can I kill ex thread?
  • What is the best way to implement this mechanism?
user148865
  • 326
  • 1
  • 5
  • 19

2 Answers2

0

There is no 100% safe way to do it in Java.

The recommend approach would be to interrupt the Execute thread

if(ex.isAlive()){
        System.out.println("yes");
        //kill the thread ex.
        ex.interrupt()
}

but for that to work, inside your Execute run() method logic you need to check if interrupted() returns true and if so, stop the computations (for example if your run method does something in a loop, first statements inside the loop could do that check. Interrupt will also break all the "blocking" operations like wait(), sleep(), IO operations, so it affect both your "code" and let's call them "system" methods (that is why for example sleep throws InterruptedException).

Nevertheless you need to be in control of the run() method code to add the necessary checks and stops its execution.

The hardcore way of stoping a thread is calling

ex.stop()

as you can see in the JavaDoc it is deprecated and should not normally used as it can cause problems (read the doc). But it is the only way of stoping thread that exectues a code that you don't have control over.

My approach would be, first to interrupt, wait to see if it worked and if not forcible stop the thread.

if(ex.isAlive()){
        System.out.println("yes");
        //kill the thread ex.
        ex.interrupt();
        ex.join(100); //give the ex thread chance to stop in a clean way
        if (ex.isAlive()) {
           ex.stop();
        }
}
Zielu
  • 8,312
  • 4
  • 28
  • 41
0

First some background info, I came across the issue to have a timeout while running a command because the program that I tried to execute would never print any debug or error information incase of error and would just keep on retrying internally by itself resulting in process stuck because there was never an error or output stream when it was retrying.

So after process.exec() or process.start() ,

It would be stuck forever at this line,

BufferedReader input = new BufferedReader(newInputStreamReader(process.getInputStream()));

As per java 1.8 with public boolean waitFor(long timeout,TimeUnit unit) method it should have "ideally" timed out after the specified timeout but in my case for some reason it never timed out may be because I was running application as a windows service (I have checked the user permissions and everything on the account but it didn't help).

So I tried to implement it with the below logic, where we would keep checking the input stream with input.ready() and a timeout flag.This simple solution worked like a charm compared to all other that existed.

See the code below:

https://stackoverflow.com/a/33265110/1212036

Community
  • 1
  • 1
xxnations
  • 575
  • 4
  • 4