1

I'm reading a server log file after an event is performed on the UI. I have a while loop which waits for certain conditions to match and then returns that line of the log. Sometimes, however, there's a case where an event occurs before the code looks at the log and cannot get the new line. This causes the while loop to just hang and this hangs until another event occurs with the provided conditions. This is problematic for obvious reasons. Is there a way to break out of the while loop after a few seconds no matter what the case maybe? Following is my code

   public String method(String, a, String b, String c) { 
    channel = session.openChannel("exec");
        ((ChannelExec) channel).setCommand(a + "\n" +  b);
        channel.connect();
        fromServer = new BufferedReader (new InputStreamReader(channel.getInputStream()));          
        String time = methodToFireAnEventInUI();
        Thread.sleep(2000);
        String x = null;
        while (true){
            x = fromServer.readLine();
            if(!x.equals(null) && x.contains(c) && x.contains(time)){
                break;
            }
        }
        msg = x.toString();
    }catch (Exception e){
        e.printStackTrace();
    }
    closeConnection();
    return msg;
    }

If you look at the above code, it hangs right at "x = fromServer.readline();" and just doesn't go anywhere, and that is where I want the logic for it to wait for an x amount of time and just abort the loop after that. My attempt of "thread.sleep" ahead of the while loop doesn't work either.

Donshon
  • 174
  • 2
  • 11
  • 1
    `readline` is a blocking call. There's nothing you can do in the same thread to work around that call hanging. – Ian McLaird Mar 09 '15 at 16:27

4 Answers4

1

You can put this logic in a separate thread and use a while like this:

class TestThread extends Thread {

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            method();
        }       

    }

    public void method() {
        try {
            // this method hangs. You can replace it with your method
            while (true) {
                sleep(100);
            }
        } catch (Exception e) {
            System.out.println("Thread is interrupted");
        }
    }
}

After that you can interrupt this thread if it takes longer than some time frame like this:

public static void main(String[] args) throws Exception {
    TestThread t1 = new TestThread();
    long startTime = System.currentTimeMillis();
    t1.start();
    long currentTime = System.currentTimeMillis();
    while (currentTime - startTime < 5000) { // you can decide the desired interval
        sleep(1000); // sleep some time
        currentTime = System.currentTimeMillis();
        System.out.println(currentTime); //print this to ensure that the program is still running
    }
    t1.interrupt(); //interrupt the thread
}
  • This looks promising, can you please elaborate? So do I call my "method" within the while loop? After that how do I use the "t1.start() and interrupt" methods? I've never used this technique before.. – Donshon Mar 09 '15 at 17:04
0

How about simply:

long timeOut = System.currentTimeMillis() + 5000; // change the value to what ever(millis)
while(System.currentTimeMillis() < timeOut){
    // do whatever 
}
Dima Maligin
  • 1,386
  • 2
  • 15
  • 30
  • 2
    I have actually tried this, but the problem is, once it goes in the loop, it wouldn't come out to check the condition provided here. Therefore, it just doesn't work, unfortunately. – Donshon Mar 09 '15 at 16:27
  • I'm inclined to believe that there are other ways of achieving this besides @Thabang Masigo solution, I'm just not to sure that passing `InputStream` around to `Thread`'s is the best solution. – Dima Maligin Mar 09 '15 at 16:47
  • @Donshon [This](http://stackoverflow.com/questions/804951/is-it-possible-to-read-from-a-inputstream-with-a-timeout) may help. – Dima Maligin Mar 09 '15 at 17:11
0

As your while loop blocks at "x = fromServer.readline();" you can just share the reader instance to another thread and make that thread close the reader after timeout. This will cause your readLine to throw exception which you can handle and proceed.

hemant1900
  • 1,226
  • 8
  • 9
0

Find answer here: How do I measure time elapsed in Java?

Try the approach below:

long startTime = System.nanoTime(); //fetch starting time
while(true ||(System.nanoTime()-startTime)<200000)
{
    // do something
}
Community
  • 1
  • 1
IgnitiousNites
  • 155
  • 1
  • 1
  • 7