做一些像
这样的事情是否安全for (int i = 0; i < 10; i++){
final int finalI = i;
new Thread(() -> {
// use finalI in the thread somehow
});
}
所以我想问的问题是,是否保证线程0..9会看到finalI分别为0..9?
例如,如果在第二次迭代中finalI被更改并且第一个线程将finalI视为1而不是0,那该怎么办。
我有99%的感觉这是不可能的,但我不知道匿名类如何存储变量,所以我不是百分百肯定。
如果anon类引用了对该变量的外部引用那么那将是错误的,但它实际上并不是一个引用,因为它是一个原语。那么heck如何将线程anon类存储变量?
在幕后,JVM是否会使它在anon线程中给出一个字段私有final int finalI然后隐含地在构造函数中设置它?
答案 0 :(得分:0)
finalI将分别为0..9。
要了解内部发生的事情,请查看将变量声明为
的内容最终
确实
让我们
public class ThreadTest {
public static void main(String[] args) {
for(int i =0; i< 9; i++) {
final int finalI = i;
new Thread(()->{
try {
Thread.sleep(1000); // assuming a delay for some operations
System.out.println(Thread.currentThread().getName()+" "+finalI);
//System.out.println(Thread.currentThread().getName()+" "+ i); // can't do this.
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
方法的局部变量保留在堆栈中,并在方法结束后立即丢失。即使在方法结束后,即使在本地声明的最终变量/对象也可以被访问,因为它们被其他类/方法引用,在这种情况下它是可运行的。
所以当我们执行
时final int finalI = i;
我们正在创建一个新的finalI变量,它既不能改变前一个变量,也不能使用这个值,因为之前的finalI是分别放在JVM堆中的。