volatile 理解
volatile是Java虚拟机里面的轻量级的同步机制
保证可见性
不保证原子性
禁止指令重排序
Java 内存模型
Java虚拟机的规范中定义了什么是Java内存模型(Java Memory Model,JMM)
Java内存模型本身是一种抽象的概念,也并不实体存在,它描述的是一组规则或者规范,通过这组鬼覅按,定义了程序中各个变量(包括实力字段,静态字段和构成素组对象的元素)的访问方式。它是用于屏蔽掉各种硬件与操作系统内存之间的访问差异,从而实现让Java程序在各种平台下都可以做到一样的运行效果,Java内存模型规范了Java虚拟机与计算机内存是如何协同工作,规定了一个线程应该如何以及什么时候可以看到其他线程修改后的共享变量的数据,以及如何同步访问共享变量。旧版本的Java内存模型并不完善,因此Java内存模型在Java 1.5时被重新修订。现在使用的Java 1.8也仍旧沿用着1.5的内存模型。
JMM关于同步的规定:
线程解锁前,必须把共享变量的值刷新到主内存
线程加锁前,必须读取主内存的最新的值到工作内存
加锁解锁是同一把锁
介于JVM运行程序的是基于线程的,且每个线程都会拥有自己的一个工作内存,工作内存就是当前线程的私有数据空间,其他线程不可访问,而Java内存模型中同时规定所有数据都必须存储在主内存,主内存是公共的内存区域,所有的线程都可以访问,但线程对数据的读取,赋值等必须在各自的工作内存中进行。不可以直接操作主内存。因此,首先需要将数据从主内存复制到自己的工作内存,然后对数据进行操作,操作完成后再将新数据写回主内存,不能直接操作主内存中的变量,各个线程中的工作内存中存储着主内存的数据副本,因此不同的线程件无法访问其他线程的工作内存,线程间的通信必须通过主内存来完成。
Java内存模型是围绕着在并发过程中如何处理原子性、可见性和有序性这三个特征来建立的。
原子性:对数据的操作是具备原子性的。有点像数据库中的事务。读取,修改,写入时一气呵成,不可分割。synchronized代码块的操作也时原子性的。
可见性:Java内存模型是通过在数据修改后将新数据同步回主内存,当一个线程修改后,是否会通知其他线程该数据已修改,致使其他线程在操作前会从主内存重新刷新数据值的过程称之为可见性。除了volatile之外,synchronized和final关键字也实现了可见性。final修饰的字段在构造器中一旦初始化完成,那在其他线程中就能看到final字段的值。
有序性:线程内表现为串行的语义,不同线程之间存在指令重排序,即两个不相关的变量赋值的先后顺序并不影响单线程的运算结果,从而编译器会对操作的变量进行重新排序。Java中提供了volatile和synchronized两个关键字来保证线程之间操作的有序性。