首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有lambda的局部AtomicReference和数组

带有lambda的局部AtomicReference和数组
EN

Stack Overflow用户
提问于 2020-02-26 06:46:09
回答 1查看 2.6K关注 0票数 3

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

代码语言:javascript
复制
    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 当我将“原子”更改为“排列”这个工作状态时:
代码语言:javascript
复制
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一起工作?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-26 07:22:49

1)守则:

代码语言:javascript
复制
 number.getAndSet(number.get() + 1);
 return number.get();

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

代码语言:javascript
复制
public void a(GlobalL globalL) {
    AtomicInteger number = new AtomicInteger(0);
    Work work = () -> {
        return number.incrementAndGet();
    };
    globalL.setWork(work);
}

2)你不能(见关于匿名课程的官方教程)

3)海事组织,这应该是一个单独的问题。简单地说,lambdas只是语法糖,它们被编译成匿名的内部类。

至于why array works correctly?的问题,答案是:it并不是出于同样的原因:为了证明它,只需将线程数增加到1000个:

代码语言:javascript
复制
   for (int i = 0; i < 1000; i++) {
        new Thread(() -> {
            globalL.printSum();
        }).start();
    }

我得到了:

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60408193

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档