java可见性
通常我们提到可见性,关键字通常是volatile 和 synchronized,
今天发现有的文章提及了final对于内存可见性的一些观点
讲道理 final 和 volatile 多少有些互斥的感觉
算了 还是上代码测一下吧
测试
我们理解的可见性是对某个字段修改了之后,其他线程也会感知到,但是final修饰的字段是不能重新赋值的,怎么办呢。
当final修饰的是数组,List的时候,我们虽然不能将声明的变量重新指向别的内存地址,但是可以修改List里边的内容
public class FinalTest {
public final List<Integer> list = new ArrayList<>();
public static void main(String[] args) {
FinalTest ft = new FinalTest();
new Thread(()->{
while(ft.list.size() == 0) {
}
System.out.println("list 大小改变");
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
ft.list.add(123);
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ft.list.size());
}
}
控制台并没有打出list 大小改变,但是把final换成volatile就可以了。
结论
关于final内存可见性,至少这种修改之后其他线程是感知不到的。
思考:final 和 volatile 可以修饰同一个变量么?
那必然不能 ,无法过编译,毕竟是有点互斥的