本文介绍: 前言小伙伴大家好,上次分析了Synchronized关键字的特点及使用方式多线程中经常提到的除了这个还有volatile,来分析该关键字的特点一、volatile的特点1.线程间可见性用volatile声明共享变量,保证了某个线程修改了该变量的值,新值对其他线程来说是立即可见的,因为volatile关键字强制修改后的值立即写入内存。1.1、案例

目录

前言

一、volatile的特点

1.线程间可见性

1.1、案例

1.2 案例分析

2、禁止指令重排

解决方案

 章末


前言

        小伙伴大家好,上次分析了Synchronized关键字的特点及使用方式多线程中经常提到的除了这个还有volatile,来分析该关键字的特点

一、volatile的特点

1.线程间可见性

        用volatile声明的共享变量,保证了某个线程修改了该变量的值,新值对其他线程来说是立即可见的,因为volatile关键字强制修改后的值立即写入内存

1.1、案例

        在main方法里,新建一个线程休眠100ms,然后修改stop变量为true,与此同时通过countNum方法计数,直到stop变量为true停止,结果如下,一直循环表明检测不到stop变为true

public class VolatileTest {

        static boolean stop = false;
        public static void main(String[] args) {
            new Thread(() -> {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                stop = true;
                System.out.println("change stop to true...");
            }).start();
            countNum();
        }
        static void countNum() {
            int i = 0;
            while (!stop) {
                i++;
            }
            System.out.println("stopped... successfully at :"+ i);
        }

}

1.2 案例分析

        解决方法之一就是使用volatile关键字来声明变量,让其他线程可见,在stop修改后第一时间获取修改后的结果如下,在i变量值为218467224的时候该线程检测stop的值为true,跳出循环打印

static volatile boolean stop = false;

2、禁止指令重排

        在编译器处理器优化指令执行顺序时,为了提高程性能可能会对指令进行重排。然而,在多线程环境下,指令重排可能会导致结果的错误或者不符合预期。使用volatile关键字修饰的变量,在读写操作前后加入特定的内存屏障memory barrier),这个内存屏障可以防止指令重排,确保操作顺序符合程序员的预期。

说人话(bushi),具体来说,volatile关键字禁止的是以下三种类型指令重排:

  • 在volatile写操作之前的读操作不能被重排到volatile写操作之后。
  • 在volatile写操作之后的写操作不能被重排到volatile写操作之前。
  • 在volatile读操作之后的读操作不能被重排到volatile读操作之前。
//伪代码举个例子

int x;
int y;

方法1(){
    x=1;
    y=1;
}

方法2(result r){
    r.r1 = y;
    r.r2 = x;
    }
在去获取上面的结果的时候,有可能会出现
4
种情况
解决方案

        在变量上添加volatile,禁止指令排序,则可以解决问题 ,注意只能将volatile添加到y变量上,因为关键字添加的屏障如下

                   

                        volatile 加在 y上                                                   volatile加在x

加在x上显然是不行的,主要是因为下面两个原则
  • 写操作加的屏障是阻止上方其它写操作越过屏障排到volatile变量写之下
  • 读操作加的屏障是阻止下方其它读操作越过屏障排到volatile变量读之上,因为此时y是正常变量也因为volatile声明了x导致y不可读

但是不用慌,有问题就会有小妙招

 章末

好了,以上就是全部内容了,下次来分析分析其他的锁(什么?还有高手)


原文地址:https://blog.csdn.net/TM007_/article/details/134677033

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_26646.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注