java - 本地 AtomicReference 和带有 lambda 的数组

标签 java lambda jvm anonymous-class

我尝试更改并使用 lambda 获取局部变量。我知道我应该对 lambda 中的局部变量使用有效的final。当我使用 AtomicReference 局部变量更改失败时:

    public class Lamb {
    public static void main(String[] args) throws InterruptedException {
        Lamb lamb = new Lamb();
        GlobalL globalL = new GlobalL();
        lamb.a(globalL);
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                globalL.printSum();
            }).start();
        }
        Thread.sleep(3000);
        System.out.println("--------After Work--------");
        globalL.printSum();
    }
    public void a(GlobalL globalL) {
        AtomicReference<Integer> number = new AtomicReference<>(0);
        Work work = () -> {
            number.getAndSet(number.get() + 1);
            return number.get();
        };
        globalL.setWork(work);
    }
}
class GlobalL {
    private Work work;
    public void printSum() {
        System.out.println(work.getAndInc());
    }
    public void setWork(Work work) {
        this.work = work;
    }
}
interface Work {
    int getAndInc();
}

每次输出不同:

  1. --------下类后--------
    97
  2. --------下类后--------
    99
    当我将 Atomic 更改为数组时,此工作正常:
public void a(GlobalL globalL) {
        Integer[] number = {1};
        Work work = () -> {
            number[0]++;
            return number[0];
        };
        globalL.setWork(work);
}

每次输出:
--------下类后--------
102

  1. 数组和原子这种情况是怎么回事?
  2. 如何使用非最终局部变量使用匿名类和 labmda?
  3. jvm 如何与 lamda 配合使用?

最佳答案

1)代码:

 number.getAndSet(number.get() + 1);
 return number.get();

是一个关键部分,因为有几个操作不是原子执行的。这就是为什么你会得到不同的结果。消除关键部分:

public void a(GlobalL globalL) {
    AtomicInteger number = new AtomicInteger(0);
    Work work = () -> {
        return number.incrementAndGet();
    };
    globalL.setWork(work);
}

2) 你不能(参见thisthe official tutorial on Anonymous Classes)

3)IMO,这应该是一个单独的问题。简而言之,lambda 只是语法糖,它们被编译成匿名内部类。

<小时/>

至于为什么数组可以正常工作?问题,答案是:不能,原因相同:++ is not an atomic operator 为了证明这一点,只需将线程数增加到 1000:

   for (int i = 0; i < 1000; i++) {
        new Thread(() -> {
            globalL.printSum();
        }).start();
    }

我得到:

--------After Work-------- 972

关于java - 本地 AtomicReference 和带有 lambda 的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60408193/

相关文章:

c# - 组合字符串时方法语法中的 Where 子句失败

java - 如何在 Linux 中使用 -vm 参数在 Eclipse RCP 产品的 Config.ini 文件中设置类路径

c++ - 在 C++ 中使用 JVM 生成代码

java - 为什么 Roo 不为 finder 生成 Spring 存储库查询方法

java - Spring MVC/Rest - 返回标准响应

c++ - 丢弃限定符未知原因 (std::bind()/lambda)

c# - lambda 的 Linq 更新问题

java - 从 Mega.nz 加载文件以在 java 项目中使用

java - 如何在@RequestParam中设置默认值为LocalDateTime

c++ - 'Chunk * _chunk = new (size) Chunk(size)' 是什么意思?