在lambda表达式中使用final变量Java

时间:2017-08-09 20:10:41

标签: java final completable-future

我有一个可以获取大量数据的应用程序,因此我想将数据分页并分别处理这些块,而不是一次处理所有数据。所以我编写了一个函数,我每隔n秒调用一次来检查块是否完成,然后处理该块。我的问题是我无法跟踪我刚刚处理了一个块的事实,并且当它可用时我应该移动到下一个块。我正在考虑下面的代码,但我不能调用multiplier++;,因为它抱怨它不再像最终变量那样表现。我想使用乘法器之类的东西,这样一旦代码处理一个块,它就不会再次处理同一个块,2)移动到下一个块。是否有可能做到这一点?是否有一个修饰符可以放在乘数上以帮助避免竞争条件?

int multiplier = 1;
CompletableFuture<String> completionFuture = new CompletableFuture<>();

final ScheduledFuture<?> checkFuture = executor.scheduleAtFixedRate(() -> {
    // parse json response
    String response = getJSONResponse();
    JsonObject jsonObject = ConverterUtils.parseJson(response, true)
      .getAsJsonObject();

    int pages = jsonObject.get("stats").getAsJsonObject().get("pages").getAsInt();

    // if we have a chunk of n pages records then process them with dataHandler function
    if (pages > multiplier * bucketSize) {
        dataHandler.apply(getResponsePaginated((multiplier - 1) * bucketSize, bucketSize));
        multiplier++;
    }
    if (jsonObject.has("finishedAt") && !jsonObject.get("finishedAt").isJsonNull()) {
        // we are done!
        completionFuture.complete("");
    }

}, 0, sleep, TimeUnit.SECONDS);

1 个答案:

答案 0 :(得分:1)

您可以使用AtomicInteger。由于这是一个可变类型,您可以将其分配给final变量,同时仍然可以更改其值。这也解决了回调之间的同步问题:

final AtomicInteger multiplier = new AtomicInteger(1);
executor.scheduleAtFixedRate(() -> {
  //...
  multiplier.incrementAndGet();
}, 0, sleep, TimeUnit.SECONDS);