【发布时间】:2014-09-21 05:00:24
【问题描述】:
我正在迭代 Iterator,其中 hasNext() 永远不会返回 false。但是,在指定时间(比如说 20 秒)之后,我想停止迭代。问题是Iterator的next()方法是阻塞的,但即便如此,在指定时间后,我只需要停止迭代即可。
这是我的示例 Iterable 和 Iterator 来模拟我的问题。
public class EndlessIterable implements Iterable<String> {
static class EndlessIterator implements Iterator<String> {
public boolean hasNext() { return true; }
public String next() {
return "" + System.currentTimeMillis(); //in reality, this code does some long running task, so it's blocking
}
}
public Iterator<String> iterator() { return new EndlessIterator(); }
}
这是我要测试的代码。
EndlessIterable iterable = new EndlessIterable();
for(String s : iterable) { System.out.println(s); }
我想把代码/逻辑放到Iterable类中创建一个Timer,所以指定的时间到了,就会抛出异常,停止迭代。
public class EndlessIterable implements Iterable<String> {
static class EndlessIterator implements Iterator<String> {
public boolean hasNext() { return true; }
public String next() {
try { Thread.sleep(2000); } catch(Exception) { } //just sleep for a while
return "" + System.currentTimeMillis(); //in reality, this code does some long running task, so it's blocking
}
}
static class ThrowableTimerTask extends TimerTask {
private Timer timer;
public ThrowableTimerTask(Timer timer) { this.timer = timer; }
public void run() {
this.timer.cancel();
throw new RuntimeException("out of time!");
}
}
private Timer timer;
private long maxTime = 20000; //20 seconds
public EndlessIterable(long maxTime) {
this.maxTime = maxTime;
this.timer = new Timer(true);
}
public Iterator<String> iterator() {
this.timer.schedule(new ThrowableTimerTask(this.timer), maxTime, maxTime);
return new EndlessIterator();
}
}
然后我尝试如下测试此代码。
EndlessIterable iterable = new EndlessIterable(5000);
try {
for(String s : iterable) { System.out.println(s); }
} catch(Exception) {
System.out.println("exception detected: " + e.getMessage());
}
System.out.println("done");
我注意到的是RuntimeException在时间到之后被抛出,然而,
- for 循环继续进行,
- 永远不会到达 catch 块,并且
- 我永远不会到达代码的末尾(打印完成)。
有什么策略、方法或设计模式可以解决我所描述的这个问题吗?
请注意
- 在我的实际代码中,我无法控制
Iterator - 我只能控制
Iterable和实际迭代
【问题讨论】:
-
您在一个完全不相关的线程中抛出异常。当然,这不会影响您的迭代。
标签: java multithreading timer iterator iterable