关于final内存可见性的探究

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 可以修饰同一个变量么?

那必然不能 ,无法过编译,毕竟是有点互斥的
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lbh199466/article/details/106266887
今日推荐