zoukankan      html  css  js  c++  java
  • Volatile

    (一) Volatile是什么

      Volatile 是Java虚拟机提供的轻量级的同步机制

    1. 保证可见性
    2. 不保证原子性
    3. 禁止指令重排

     (二) JMM (Java内存模型 Java Memory Model)

      是一种抽象概念,并不保证可见性,原子性,有序性

      JMM关于同步的规定

    1. 线程解锁前,必须把共享变量的值刷新回内存
    2. 线程加锁前,必须读取主内存的最新值到自己的工作内存(自己线程私有数据区域)
    3. 加锁解锁是同一把锁

      Java 内存模型中规定所有的变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问

      但是线程对变量的操作必须在工作内存中进行,首先要将变量从主内存拷贝到自己的工作内存空间

      然后对变量进行操作,操作完成后再将变量写回主内存

      


     (三) Volatile 保证可见性 代码示例

      Volatile可见性:及时通知其他线程,主物理内存的值已经被改变

      不加Volatile

     1 package com.Interview.study.thread;
     2 import java.util.concurrent.TimeUnit;
     3 class MyData{
     4     int number = 0;
     5     public void addT060(){
     6         this.number = 60;
     7     }
     8 }
     9 
    10 public class VolatileDemo {
    11 
    12     public static void main(String[] args) {
    13         MyData myData = new MyData();
    14         new Thread(() -> {
    15             System.out.println(Thread.currentThread().getName() + "	 come in ");
    16             try {
    17                 TimeUnit.SECONDS.sleep(3);
    18             }catch (InterruptedException e){
    19                 e.printStackTrace();
    20             }
    21             myData.addT060();
    22             System.out.println(Thread.currentThread().getName() + "	 updated number value:" + myData.number);
    23         },"AAA").start();
    24 
    25         while (myData.number == 0){
    26 
    27         }
    28 
    29         System.out.println(Thread.currentThread().getName() + "	 mission is over ");
    30     }
    31 }

      运行结果

      

        加Volatile

     1 package com.Interview.study.thread;
     2 import java.util.concurrent.TimeUnit;
     3 class MyData{
     4     volatile int number = 0;
     5     public void addT060(){
     6         this.number = 60;
     7     }
     8 }
     9 
    10 public class VolatileDemo {
    11 
    12     public static void main(String[] args) {
    13         MyData myData = new MyData();
    14         new Thread(() -> {
    15             System.out.println(Thread.currentThread().getName() + "	 come in ");
    16             try {
    17                 TimeUnit.SECONDS.sleep(3);
    18             }catch (InterruptedException e){
    19                 e.printStackTrace();
    20             }
    21             myData.addT060();
    22             System.out.println(Thread.currentThread().getName() + "	 updated number value:" + myData.number);
    23         },"AAA").start();
    24 
    25         while (myData.number == 0){
    26 
    27         }
    28 
    29         System.out.println(Thread.currentThread().getName() + "	 mission is over ");
    30     }
    31 }

      运行结果

      


     (四) Volatile 不保证原子性 代码示例

     1 package com.Interview.study.thread;
     2 import java.util.concurrent.TimeUnit;
     3 class MyData{
     4     volatile int number = 0;
     5     public void addT060(){
     6         this.number = 60;
     7     }
     8 
     9     public  void addNumber(){
    10         number++;
    11     }
    12 }
    13 
    14 public class VolatileDemo {
    15 
    16     public static void main(String[] args) {
    17         MyData myData = new MyData();
    18 
    19         for(int i = 0 ; i < 20 ; i++){
    20             new Thread(() -> {
    21                 for(int j = 0 ;j < 1000 ; j++){
    22                     myData.addNumber();
    23                 }
    24             },String.valueOf(i)).start();
    25         }
    26 
    27         while (Thread.activeCount() > 2){
    28             Thread.yield();
    29         }
    30         System.out.println(Thread.currentThread().getName() + "	 finally number value " + myData.number);
    31     }
    32 }

    代码起了20个线程对其进行++ 1000次 

    预期结果应该是20000  但是执行结果有丢失 

    不保证原子性


     (五)指令重排

       

      多线程环境中线程交替执行,由于编译器优化重排的存在

       两个线程中使用的变量能否保证一致性是无法确定的,结果无法预测


         细雨

  • 相关阅读:
    Android JNI开发摘录(二)之JNI数组处理
    基于HTTP协议的下载功能实现
    javascript中的事件冒泡和事件捕获
    JavaScript模仿块级作用域
    javascript表单的Ajax 提交插件的使用
    论学历与经验
    使用Palette抽取图片颜色
    通过脚本和EL表达式获取域中数据
    需求分析
    Tomcat简介
  • 原文地址:https://www.cnblogs.com/misscai/p/12708167.html
Copyright © 2011-2022 走看看