Lambda表达式下访问外部变量问题
作者:勤快的小蚂蚁
这篇文章主要介绍了Lambda表达式下访问外部变量问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
Lambda表达式可以访问给它传递的变量,访问自己内部定义的变量,同时也能访问它外部的变量。
不过lambda表达式访问外部变量 有一个非常重要的限制:
变量不可变(只是引用不可变,而不是真正的不可变) 遇到问题:
有同学反馈Stream循环处理集合时,可能需要操作一个中间变量进行复制或者比较操作。
做了一个简单的示例
如下:
(例子)统计取模2的数量
会提示(封闭范围中定义的局部变量a必须是final或effectively final):
当我们加入final进行变量修饰(无法分配最终的局部变量A):
原因
不过lambda表达式访问外部变量有一个非常重要的限制:变量不可变(只是引用不可变,而不是真正的不可变)。
解决方案
java.util.concurrent.atomic.* AtomicInteger说明
AtomicInteger是一个提供原子操作的Integer类,通过线程安全的方式操作加减。
AtomicReference说明:
它是通过"volatile"和"Unsafe提供的CAS函数实现"原子操作。
1.value是volatile类型。这保证了:当某线程修改value的值时,其他线程看到的value值都是最新的value值,即修改之后的volatile的值。
2. 通过CAS设置value。这保证了:当某线程池通过CAS函数(如compareAndSet函数)设置value时,它的操作是原子的,即线程在操作value时不会被中断。
扩展
a.incrementAndGet(); //前者,先+1,再返回 a.get()//获取当前a的值 a.getAndIncrement()//后者,先返回,再 +1
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。