Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节
码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令
volatile定义:Java编程语言允许线程访问共享变量,为了
确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量。Java语言
提供了volatile,在某些情况下比锁要更加方便。如果一个字段被声明成volatile,Java线程内存
模型确保所有线程看到这个变量的值是一致的。一个volatile变量的单个读/写操作,与一个普通变量的读/写操作都
是使用同一个锁来同步,它们之间的执行效果相同
一、java中提供的稍弱得同步机制,即volatile变量,确保将变量得更新操作通知到其他线程,声明为此类型后,编译器与运行器都会注意到这个变量 是共享得,因此不会将变量与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者其他处理器不可见得地方。
二、加锁机制既可以确保可见性又可以确保原子性,volatile只能确保可见性。
三、使用条件:
1)对变量得写入操作不依赖变量的当前值,或者你能确保只有单个线程更新变量得值。
2)该变量不会与其他状态变量一起纳入不变性条件中。
3)在访问变量时不需要加锁。
总而言之:volatile有下列特性
可见性:对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写
入。
·原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不
具有原子性。
四、
上面讲的是volatile变量自身的特性,对程序员来说,volatile对线程的内存可见性的影响
比volatile自身的特性更为重要,也更需要我们去关注。
从JSR-133开始(即从JDK5开始),volatile变量的写-读可以实现线程之间的通信。
从内存语义的角度来说,volatile的写-读与锁的释放-获取有相同的内存效果:volatile写和
锁的释放有相同的内存语义;volatile读与锁的获取有相同的内存语义。
五、
volatile读的内存语义如下。
当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主
内存中读取共享变量。
- ·线程A写一个volatile变量,实质上是线程A向接下来将要读这个volatile变量的某个线程 发出了(其对共享变量所做修改的)消息。
- ·线程B读一个volatile变量,实质上是线程B接收了之前某个线程发出的(在写这个volatile变量之前对共享变量所做修改的)消息。
- ·线程A写一个volatile变量,随后线程B读这个volatile变量,这个过程实质上是线程A通过主内存向线程B发送消息。