JAVA多线程面试总结之Volatile和synchronized的实现原理

前言

对于Volatile和synchronized,学过多线程的人再熟悉不过了,Volatile主要实现的是内存可见性,synchronized主要是获得锁。具体原理以及过程更多的是在JVM里去实现的,jdk只是简单地封装,在以后的文章里,我会分享一下JVM的Hotspot锁相关源码。

什么是JMM

JMM(Java Memory Mode)Java内存模型。JMM主要定义了线程和主内存之间的抽象关系。JMM主要是在并发过程中如何处理可见性原子性有序性的问题

JMM的共享与非共享

首先我们思考一下,什么对象是内存共享的?什么不是?

线程之间共享:

java中,堆内存里:实例域,静态域,数组元素等
堆内存的特性:线程之间共享

线程之间不共享:
局部变量,方法参数、异常等

并发编程中的重点问题

1、线程之间如何通信?wait(),notify(),notifyall()

命令编程模型里:
多线程的共享内存模型
线程A/B什么时候从主内存获取数据刷新本地缓存?

答:不确定
正是因为不确定,才导致了线程安全与可见性的问题
怎么解决?
使用Volatile和synchronized

a) 共享内存  -隐式通信

 b)  消息传递 -显式通信

2、线程之间如何同步?

在共享内存的并发模型中,同步是显示做的:synchronized
在消息传递的并发模型中,由于消息的发送必须在消息接收之前,所以同步是隐式

Volatile保证可见性原理

功能:原子性,可见性;但不能做到复合操作的原子性

//复合操作不能保证原子性举例:
//多线程操作add方法
Volatile int  i;
public void add(){
	i++;
}

1.对于声明了Volatile的变量进行写操作的时候,JVM会向处理器发送一条Lock前缀的指令。会把这个变量所在缓存行的数据写回到系统内存

2.在多处理的情况下,保证各个处理器缓存一致性的特性,就会实现缓存一致性协议

synchronized锁的原理

功能:可重入锁,互斥性,可见性

synchronized的实现代码在Hotspot里,jdk只是简单封装,为了验证流程,我们写一个测试类:

public class App2 {

    public static void main(String[] args) throws InterruptedException{
        synchronized (App2.class){}
        test();
    }
    public static synchronized void test(){}

}

然后编译,看字节码文件.class文件

然后对字节码文件执行

javap -v App2.class

得到:
在这里插入图片描述
基于JVM实现的monitorenter ,monitorexit
实现了获得锁,运行,释放锁的过程
在这里插入图片描述

发布了47 篇原创文章 · 获赞 5 · 访问量 1888

猜你喜欢

转载自blog.csdn.net/qq_34361283/article/details/102914408