zoukankan      html  css  js  c++  java
  • java之内存可见型

    1、可见性的概念

      一个线程对于共享变量的修改,能够及时被其他的线程看到。

    2、什么是共享变量

      一个变量在多个线程中的工作内存中都存在变量副本,那么这个变量在这几个线程之间共享。

    3、Java线程的工作规则

      (1)线程对于共享变量的所有操作都必须在自己的工作内存中,不能对主内存进行直接的操作

      (2)不同线程之间无法直接通过访问其他线程工作内存的变量,线程间变量传递时通过主类存来完成的

      

    4、synchronizied的原子性和可见性:

      线程执行互斥代码的过程:

      1、获得互斥锁

      2、清空工作内存

      3、中从主内存中拷贝变量的最新副本到工作内存

      4、执行代码块

      5、将更改以后的共享变量的值刷新到住内存

      6、释放互斥锁

    5、指令重排序:代码的书写顺序与实际执行的顺序不同,指令重排序是编译器或者处理器为了提高程序性能而做的优化

      重排序不会给单线程带来内存可见性问题,但是在多线程的条件下,内存可见性就会出现问题

      1、编译器优化的重排序(编译器优化)

      2、指令级并行的重排序(处理器优化)

      3、内存系统的重排序(处理器优化)

    6、as-if-serial:无论如何进行重排序,执行结果应该和顺序执行的结果一致

    7、volatile实现可见性:通过加入内存屏障和禁止重排序优化实现

      1、对volatile变量执行写操作时,在写操作后面添加一条store屏障指令(将缓冲区值强制刷新到主内存)

      2、对volatile变量执行读操作时,在读操作后面添加一条load屏障指令(让缓冲区值失效,要从主内存中重新读值)

      3、通俗的来讲:volatile变量每次被线程访问时,都强迫从主内存中读取该变量的值,当变量值发生变化时,有强迫刷新到主内存,

       这样在任意时刻,不同线程总能够看到该变量的最新值,以此实现内存可见性

      4、线程写volatile变量

        1、改变线程工作内存中volatile变量副本的值

        2、将改变副本的值从工作内存刷新到主内存

      5、线程读volatile变量

        1、从主内存中读取volatile变量的最新值到线程的工作内存中

        2、从线程的工作内存中读取volatile变量的副本

      6、为什么volatile变量不能保证原子性:

        volatile int num=0;

        num++;

        对于num++的操作要经历以下步骤

        1、读取num的值

        2、num+1;

        3、写入num的值

        这三步操作不能保证原子性

      7、volatile变量的使用场景

        1、对变量的写入操作不能依赖当前的值(不能与之前的值有关系)比如boolean,天气的变化

        2、该变量没有包含在具体的其他变量中

  • 相关阅读:
    sqlplus中设定行大小、页大小、字符列格式、数字列格式、清屏
    位图索引
    B树索引
    Oracle列自增实现(3)-DEFAULT Values Using Sequences
    Oracle列自增实现(2)-Identity Columns in Oracle Database 12c Release 1 (12.1)
    oracle列自增实现(1)-Sequence+Trigger实现Oracle列自增
    ORA-01502: 索引或这类索引的分区处于不可用状态
    Oracle中的rowid
    Multitenant Architecture---PDB与CDB
    ODI Studio拓扑结构的创建与配置(Oracle)
  • 原文地址:https://www.cnblogs.com/googlemeoften/p/5116727.html
Copyright © 2011-2022 走看看