Java 并发编程关键字(volatile、synchronized)语义及其实现细节

一、Java 程序执行过程概述

Java 源文件编译成java字节码,执行时JVM将字节码载入到内存中 ,再由语言解释器和JIT转换成所在机器的汇编指令交给CPU执行。

二、Java 并发编程面对的挑战

Java 语言设计之初即选择支持多线程,java先天支持多线程的特性使得其良好的适应了现代CPU运算能力的提升及多核心的发展方向。并发编程的目的是,在保证程序运行结果正确的前提下尽可能的压榨CPU、IO和总线从而提升程序的执行效率。并发编程的挑战就是如何保证程序在多线程执行时能够得到正确的结果。程序的运行可以简单的理解为{输入数据}---->程序操作数据---->{输出结果};所以多个线程同时执行一段代码时要保证正确性就是要保证对共享变量进行有序性的、原子性的、一致性的操作,即要避免三种意外情况 ;一、避免编译器和CPU对指令优化重新排序导致的执行顺序错误,二、避免线程上下文切换导致的导致的原子性问题,三、避免本地内存数据的操作结果对其他线程不可见的问题。

Java 并发编程关键字(volatile、synchronized)语义及其实现细节

三、JAVA 并发编程关键字

1、volatile 

volatile 保证共享变量的可见性,意思是当一个线程修改了共享变量时,其他线程能够读到这个修改后的值。Java语言规范第3版中对 volatile 定义如下:Java 编程语言允许线程访问共享变量,为了确保共享变量能够被准确和一致的更新,线程应该确保通过排他锁单独获得这个变量。

实现原理:volatile  变量更新时,处理器声言Lock信号,锁定缓存变量的主内存将更新刷新到主存。其他处理器通过总线嗅探技术探测到主存刷新,则将其对应缓存行数据设置为失效。

2、synchronized

synchronized 同步锁 确保同一时刻只有个线程执行被锁定的代码。synchronized 锁有三种形式 1、synchronized  方法是锁定当前实例对象,2、synchronized 静态方法是锁定当前类的Class对象,3、对于synchronized (Object)代码块是锁定Object对象。

实现原理:线程执行到synchronized 代码块的起始位置时尝试获取synchronized 锁定的对象的 monitor,当monitor被持有后 synchronized代码将处于锁定状态,其他线程需要等待到monitor被持有线程释放后重新尝试获取monitor。

3、volatile 和 synchronized 比较

volatile 执行成本低不会引起线程上下文切换和调度,锁定的是单个变量。

synchronized  会引起线程上下文切换和调度,锁定的是一段代码。