我正在使用Stream.generate
从Instagram获取数据。由于instagram限制每小时的通话次数,因此我希望generate
的运行频率降低,而不是每2秒运行一次。
我之所以选择这样的标题,是因为我离开了ScheduledExecutorService.scheduleAtFixedRate
,这就是我要寻找的。我确实意识到流中间操作是惰性的,无法按计划调用。如果您对标题有更好的主意,请告诉我。
所以我再次希望各代之间至少有2秒的延迟。
我的尝试未考虑generate
之后的操作所耗费的时间,这可能要花费比2s更长的时间:
Stream.generate(() -> {
List<MediaFeedData> feedDataList = null;
while (feedDataList == null) {
try {
Thread.sleep(2000);
feedDataList = newData();
} catch (InstagramException e) {
notifyError(e.getMessage());
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return feedDataList;
})
最佳答案
据我了解,您的问题是要解决两个问题:
以固定的速率而不是固定的延迟等待
为未知数量的项目创建一个流,该流允许进行处理直到某个时间点(即不是无限的)
您可以通过使用基于截止日期的等待来解决第一个任务,而通过实施Spliterator
可以解决第二个任务:
Stream<List<MediaFeedData>> stream = StreamSupport.stream(
new Spliterators.AbstractSpliterator<List<MediaFeedData>>(Long.MAX_VALUE, 0) {
long lastTime=System.currentTimeMillis();
@Override
public boolean tryAdvance(Consumer<? super List<MediaFeedData>> action) {
if(quitCondition()) return false;
List<MediaFeedData> feedDataList = null;
while (feedDataList == null) {
lastTime+=TimeUnit.SECONDS.toMillis(2);
while(System.currentTimeMillis()<lastTime)
LockSupport.parkUntil(lastTime);
try {
feedDataList=newData();
} catch (InstagramException e) {
notifyError(e.getMessage());
if(QUIT_ON_EXCEPTION) return false;
}
}
action.accept(feedDataList);
return true;
}
}, false);