java volatile语义

volatile是用来保证可见性的。

  • 线程在执行过程中,所有的数据都保留在自己的本地内存中,各个线程的本地内存相互独立,互不影响。一般直到线程执行完毕后再写到主存。这样线程操作共享变量时,会有存在数据不一致问题,volatile就是为了让共享变量及时更新到主存中。
  • volatile 不具有原子性,只是保证前一秒取出来的数据是最新的,但是对于后一秒别的线程修改了数据是没有办法的,对于count++的操作和a=b的操作来讲是没有作用的。

volatile语义

  • 当写一个 volatile 变量时,JMM 会把该线程对应的本地内存中的共享变量值刷新到主内存。
  • 当读一个 volatile 变量时,JMM 会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。

实例:

a,test是同一个对象的两个引用。
 private static volatile  Test test = new Test("4545",45);
     static Test a = test;
    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            while ("4545".equals(test.getName())){
            }
        }).start();

        Thread.sleep(100);
        a.setName("343434");
在上面的例子中,test对象加了volatile。所以子线程test.getName();一直能获取到主存的数据,所以当主线程更改的时候,子线程能够读到从而不会死循环。
 private static volatile  Test test = new Test("4545",45);
     static Test a = test;
    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            while ("4545".equals(a.getName())){
            }
        }).start();

        Thread.sleep(100);
        a.setName("343434");

这个就会死循环了,因为子线程先执行,所以子线程的本地内存中a的值不会随主线程更改而发生改变。a.setName()改成test.setName()也不行,子线程没结束之前,是不会去主线程读数据的。

  • 针对死循环的情况,我们可以让子线程读取一个volatile变量,因为子线程先执行,所以要在循环里面写一个读volatile变量。
  while ("4545".equals(a.getName())){
  			test.getName();
       }

这样他就会放弃子线程的本地内存,从主存中加载数据,100ms后主线程更改name的值,循环就停止了。

最后

  • a在子线程里的值和在主线程的值是不一样的。
 private static volatile  Test test = new Test("4545",45);
    private static volatile  Test test1 = new Test("4545",45);
     static Test a = test;
    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            while ("4545".equals(a.getName())){
                System.out.println("子线程中a的值 "+a.getName());
            }
        }).start();

        Thread.sleep(100);
        a.setName("343434");
        while (true){
            System.out.println("主线程中a的值 "+a.getName());
        }


    }

运行结果

j结果

发布了21 篇原创文章 · 获赞 24 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_30332665/article/details/105385290
今日推荐