固定时间后中止循环

时间:2011-05-03 13:34:52

标签: java loops concurrency

我有一个线程,我有一个无限循环,做一些网络的东西。似乎每次我这样做都没有得到响应,因此线程会挂起几秒钟,这会给我的软件带来严重问题。我需要的是循环的某种“期限”,如果它需要更多(例如100ms)重新启动。

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

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

}

(这不是真正的阶级...只是为了得到我的意思。)

任何想法如何处理这个?

更新 我建议用一个单独的线程来处理它。实际上我使用了Callable因为我需要一个返回值。

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();
        }

但我现在面临的问题是executor.shutdownNow()没有终止挂起的Callable任务(这是根据文档的正确行为)。有没有办法杀死执行者任务? (我知道这不是一个干净的解决方案,但有些请求是由库处理的)

5 个答案:

答案 0 :(得分:3)

您可以将您的网络内容放入单独的线程中并运行几秒钟,例如:

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
 }

答案 1 :(得分:2)

Google Guava的TimeLimiter可能会满足您的需求。

  

[TimeLimiter]生成代理,对代理对象的方法调用施加时间限制。

答案 2 :(得分:0)

道歉,如果这是错误的,因为我不是Java开发人员,但从一般的编程角度来看,你应该让你的方法花费时间返回某种形式的TimeoutException

你可以在循环中捕获它,然后它会自动重启。

这不是循环的问题,也不是你在其中调用的方法。

另一种方法是在单独的线程上运行耗时的操作,这样就不会挂起任何东西。然后,您可以随时通知主(UI)线程完成。

答案 3 :(得分:0)

你的无限循环占用了CPU。尝试添加50毫秒左右的延迟,这样您就可以暂时让CPU处理其他任务。更好的是,使用Timer安排您的任务有一定的延迟和TimerTask

答案 4 :(得分:0)

你应该在超时后中断线程。查看java concurrency tutorial