zoukankan      html  css  js  c++  java
  • Java 中 static 和 volatile 关键字的区别?

    • static指的是类的静态成员,实例间共享
    • volatile跟Java的内存模型有关,线程执行时会将变量从主内存加载到线程工作内存,建立一个副本,在某个时刻写回。valatile指的每次都读取主内存的值,有更新则立即写回主内存。

    理解了这两点,逐句再来解释你的困惑:

    1. “既然static保证了唯一性”:static保证唯一性,指的是static修饰的静态成员变量是唯一的,多个实例共享这唯一一个成员。
    2. “那么他对多个线程来说都是可见的啊”:这里,static其实跟线程没太大关系,应该说对多个对象实例是可见的。你说对多个线程可见,虽然没什么毛病,因为静态变量全局可见嘛,但是把这个理解转到线程的上线文中是困惑的起因。
    3. “volatile保证了线程之间的可见性”:因为线程看到volatile变量会去读取主内存最新的值,而不是自个一直在那跟内部的变量副本玩,所以保证了valatile变量在各个线程间的可见性。
    4. “那么修改的时候只要是原子操作,那么就会保证它的唯一性了吧”:此时你说的“唯一性”,指的是各个线程都能读取到唯一的最新的主内存变量,消除了线程工作内存加载变量副本可能带来的线程之间的“不唯一性”。这里“唯一性”的含义跟第一句说的“唯一性”是不一样的。
    5. “这两个在我理解上我觉得差不多。”:其实解决问题的“场景”是完全不一样的。
    造成理解困惑最大的原因在于,这两个场景略有类似,以致混淆了:
    • 场景1:各个类的实例共享唯一一个类静态变量
    • 场景2:各个线程共同读取唯一的最新的主内存变量的值,只保证可见性,它不足以保证数据的同步性。
  • 相关阅读:
    VirtualBox 下USB 设备加载的步骤及无法加载的解决办法
    浅析:setsockopt()改善socket网络程序的健壮性
    减小Gcc编译程序的体积
    linux下查看系统进程占用的句柄数
    Linux下高并发socket最大连接数所受的各种限制
    spring-jpa通过自定义sql执行修改碰到的问题
    阿里巴巴Java开发手册中的DO、DTO、BO、AO、VO、POJO定义
    sql select时增加常量列
    CASE WHEN 及 SELECT CASE WHEN的用法
    MYSQL常见运算符和函数
  • 原文地址:https://www.cnblogs.com/huangjinyong/p/9540849.html
Copyright © 2011-2022 走看看