我有一个线程,我有一个无限循环,做一些网络的东西。似乎每次我这样做都没有得到响应,因此线程会挂起几秒钟,这会给我的软件带来严重问题。我需要的是循环的某种“期限”,如果它需要更多(例如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任务(这是根据文档的正确行为)。有没有办法杀死执行者任务? (我知道这不是一个干净的解决方案,但有些请求是由库处理的)
答案 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)
答案 4 :(得分:0)
你应该在超时后中断线程。查看java concurrency tutorial。