gpt4 book ai didi

java - 为什么实例字段不需要是 final 或有效 final 才能在 lambda 表达式中使用?

转载 作者:行者123 更新时间:2023-12-04 11:03:04 26 4
gpt4 key购买 nike

我正在用 Java 练习 lambda 表达式。根据 Java SE 16 Lambda Body 的 Oracle 文档,我知道局部变量需要是 final 或有效 final 的:

Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be final or effectively final (§4.12.4), as specified in §6.5.6.1.


但它没有说为什么。搜索我发现了这个类似的问题 Why do variables in lambdas have to be final or effectively final? ,其中 StackOverflow 用户“snr”回复了下一个引用:

Local variables in Java have until now been immune to race conditions and visibility problems because they are accessible only to the thread executing the method in which they are declared. But a lambda can be passed from the thread that created it to a different thread, and that immunity would therefore be lost if the lambda, evaluated by the second thread, were given the ability to mutate local variables.


  • 来源:Why the restriction on local variable capture?

  • 这就是我的理解:一个方法一次只能由一个线程(比如说 thread_1)执行。这确保该特定方法的局部变量仅由 thread_1 修改。另一方面,可以将 lambda 传递给不同的线程 (thread_2),因此...如果 thread_1 完成 lambda 表达式并继续执行方法的其余部分,则它可能会更改局部变量的值,并且,在同时,thread_2 可能会更改 lambda 表达式中的相同变量。然后,这就是存在此限制的原因(局部变量需要是 final 或有效 final 的)。
    对不起,很长的解释。我做对了吗?
    但接下来的问题是:
  • 为什么这种情况不适用于实例变量?
  • 如果 thread_1 与 thread_2 同时更改实例变量会发生什么情况(即使它们没有执行 lambda 表达式)?
  • 实例变量是否以另一种方式保护?

  • 我对Java没有太多经验。对不起,如果我的问题有明显的答案。

    最佳答案

    实例变量存储在堆空间中,而局部变量存储在堆栈空间中。每个线程维护自己的堆栈,因此局部变量不会在线程之间共享。另一方面,堆空间由所有线程共享,因此多个线程可以修改实例变量。有多种机制可以使数据线程安全,您可以在该平台上找到许多相关讨论。为了完整起见,我在下面引用了 http://web.mit.edu/6.005/www/fa14/classes/18-thread-safety/ 的摘录

    There are basically four ways to make variable access safe inshared-memory concurrency:

    • Confinement. Don’t share the variable between threads. This idea is called confinement, and we’ll explore it today.
    • Immutability. Make the shared data immutable. We’ve talked a lot about immutability already, but there are some additional constraintsfor concurrent programming that we’ll talk about in this reading.
    • Threadsafe data type. Encapsulate the shared data in an existing threadsafe data type that does the coordination for you. We’ll talkabout that today.
    • Synchronization. Use synchronization to keep the threads from accessing the variable at the same time. Synchronization is what youneed to build your own threadsafe data type.

    关于java - 为什么实例字段不需要是 final 或有效 final 才能在 lambda 表达式中使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67065119/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com