我正在使用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);

09-11 18:36
查看更多