Java:如何更新Runnable lambda中使用的变量?

时间:2014-11-01 22:59:24

标签: java lambda scheduledexecutorservice

我有以下代码。我在ScheduledExecuterService方法中使用scheduleNumbers()来显示一系列指定毫秒数的随机数。但是,我似乎无法更新curNumber lambda中显示的setNumber作为"从lambda表达式引用的局部变量必须是最终的或有效的最终版本" (非常有用)。没有使用线程有没有办法解决这个问题?完整代码位于下面的pastebin链接中。

private void printNumbers(int[] randomNumbers) {
    int speed = DIFF_TIMES[difficulty.getSelectedIndex()];
    int amount = BASE_AMOUNT + currentScore;
    answerField.setEditable(false);
    scheduleNumbers(randomNumbers, speed, amount);
    currentNumberLab.setText("");
    answerField.setEditable(true);
}

public void scheduleNumbers(int[] randomNumbers, int speed, int amount) {
    int curNumber = 0;
    long initialDelay = 1000;
    final Runnable setNumber = () -> {
        currentNumberLab.setText(Integer.toString(randomNumbers[curNumber]));
        System.out.println("Set to " + randomNumbers[curNumber]);
    };
    final ScheduledFuture<?> setNumberHandle = scheduler.scheduleAtFixedRate(setNumber, initialDelay, speed, MILLISECONDS);
    scheduler.schedule(() -> {
        setNumberHandle.cancel(true);
    }, (speed*amount)+initialDelay, MILLISECONDS);
}

Full code

为清晰起见编辑:

我希望能够增加curNumber,以便每次setNumber运行时,都会将currentNumberLab设置为Integer.toString(randomNumbers[curNumber++])

1 个答案:

答案 0 :(得分:5)

实际上它确实很有用......

尝试以下方法:

public void scheduleNumbers(int[] randomNumbers, int speed, int amount) {
final int curNumber = 0;

它必须是final,因为一旦该方法完成,您将在线程内部松散对局部变量的引用。该方法将完成,但线程可能仍在运行。声明一个局部变量fi​​nal可以帮助您解决这个问题。

如果您想在线程中更新curNumber,请使用AtomicInteger:

public void scheduleNumbers(int[] randomNumbers, int speed, int amount) {
final AtomicInteger curNumber = new AtomicInteger();
long initialDelay = 1000;
final Runnable setNumber = () -> {

    currentNumberLab.setText(Integer.toString(randomNumbers[curNumber.incrementAndGet()]));
    System.out.println("Set to " + randomNumbers[curNumber.get()]);
};