0

I hava a thread in which I have an infinite loop, doing some network stuff. It appears that I don't get a response every time i'm doing this so the thread hangs for several seconds which causes serious problems to my software. What I need is some kind of "deadline" for the loop, if it takes more then (e.g. 100ms) restart again.

private boolean active = true;
public void run(){

   while(active){
       //some network stuff e.g:
       dnshandler.reverselookup("8.8.8.8");
   }

}

(this is not the real class... it's just to get an impression of what I mean.)

Any Ideas how to handle this?

Update: I handeled it with a seperate Thread as suggested. Actually I used a Callable becouse I need a return value.

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
        try {
            List<Future<String>> results = executor.invokeAll(Arrays.asList(new CallableClass()), 500), TimeUnit.MILLISECONDS);
            for (Future<String> current : results) {
                if (!current.isCancelled()) {
                    someValue = current.get();
                } else {
                    // timeout
                    executor.shutdownNow();
                }
            }

        } catch (Exception e) {
            //handle it!
            e.printStackTrace();
        }

But the problem I face now is, that executor.shutdownNow() isn't terminating the hanging Callable task(which is the correct behaviour according to the Documentation). Is there a way to kill an executor task? (I know this is not a clean solution but some of the requests are handled by a library)

rob
  • 2,904
  • 5
  • 25
  • 38

5 Answers5

3

You can put your networking stuff into a separate thread and run it for a couple of seconds for instance:

int timeoutTime = ...
Runnable networkingStuff = ... // put the networking in here
Thread thread =new Thread(networkingStuff);
thread.start();
try {
    thread.join(timeoutTime);
    if(thread.isAlive()) {
        thread.interrupt();
    }
} catch (InterruptedException e) {
    // catch here the interruption
 }
Rick-Rainer Ludwig
  • 2,371
  • 1
  • 26
  • 42
  • I didn't think about join, this could work. Just for confirmation, if the "networking thread" finishes within the `timeoutTime` I end up in the try part of the try-catch-block, else in the catch. Either way my infinite loop continues? – rob May 03 '11 at 14:11
  • You end up in the catch block, if the thread is interrupted abnormally. This should not happen in normal working conditions. You should always end up in "if (thread.isAlive())" under nprmal conditions. If thread finished on its own, then thread.isAlive() == false. If it is still running after the timeout, then thread.isAlive() == true and you kill the thread with thread.interrupt(). In your endless loop you should check for Thread.interrrupted() == true. If it is the case, you should finish the loop by calling break or setting a variable which is checked in the loop conditions. – Rick-Rainer Ludwig May 03 '11 at 18:46
  • Ok thank you. I implemented this as you supposed and it is working locally. I will add it into the next testing release and let you know how it worked out under full load. Thanks! – rob May 04 '11 at 10:10
2

Google Guava's TimeLimiter may do what you need.

[TimeLimiter] produces proxies that impose a time limit on method calls to the proxied object.

Rich
  • 15,602
  • 15
  • 79
  • 126
0

Apologies if this is wrong as I'm not a Java developer, but from a general programming perspective you should have your method that may take time return some form of TimeoutException.

You can catch this in your loop and then it will automatically restart.

This isn't a problem with the loop, moreso the method(s) you're calling within.

An alternative approach would be to run your time-consuming operations on a separate thread, so that nothing hangs. You can then notify the main (UI) thread of completion at any time.

Rudi Visser
  • 21,350
  • 5
  • 71
  • 97
  • I thought of throwing a thread each time I call time-consuming methods becouse this is kind of the standard approach for handling blocking functions. But I'm a bit scared to throw several hundred threads a second, or is that not a problem? Anyway, I wll look into the TimeoutException approach and report back. Thx :) – rob May 03 '11 at 13:48
  • You would quite possibly encounter a performance hit whilst the threads are created yes. A better idea would just be to have the whole loop in your thread, rather than the operation. – Rudi Visser May 03 '11 at 13:50
  • The whole loop is already in a seperated thread. I have a producer thread and a few consumer threads. The thread mentioned is a consumer thread. Problems occur if all consumer threads hang becouse there is no response, this leads to an out of memory exception (which can be avoided using a smaller buffer between producer or consumer( -->leads to data loss since the producer cannot produce) or increasing the heap size, which is more a workaround and leads to other problems). I'm still trying to catch a `TimeoutException`... will post my progress later. – rob May 03 '11 at 15:13
  • 1
    Fair enough, sorry I couldn't be more specific or provide any code - As I say not a Java developer, just trying to help! ^_^ – Rudi Visser May 03 '11 at 15:23
0

Your infinite while loop is hogging the CPU. Try adding a delay of 50 ms or so, so that you give a small break for the CPU to attend to other tasks. Better yet, schedule your task using Timer with a certain amount of delay and TimerTask.

asgs
  • 3,928
  • 6
  • 39
  • 54
0

You should interrupt the thread after timeout. Check out java concurrency tutorial.

Yasin Bahtiyar
  • 2,357
  • 3
  • 18
  • 18