21 synchronized
Posted cathy_mu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了21 synchronized相关的知识,希望对你有一定的参考价值。
synchronized
被他修饰的方法或代码块在任一时刻只有一个线程执行。
使用synchronized
修饰实例方法=对实例加锁,执行前需要获得实例的锁
synchronized void method() { //业务代码 }
修饰静态方法 = 对类加锁
synchronized static void method() { //业务代码 }
修饰代码块 = 给指定对象/类加锁
synchronized(this) { //业务代码 } synchronized(类.class){ //blabla }
双重校验锁实现单例模式 线程安全
public class Singleton{ private volatile static Singleton uniqueInstance; private Singleton(){ } public static Singleton getInstance(){ //先判断对象是否已经实例过 if (uniqueInstance == null){ synchronized (Singleton.class){ if (uniqueInstance == null){ uniqueInstance = new Singleton(); } } } } }
上面代码为什么要用volatile
uniqueInstance = new Singleton();的步骤
1.给uni分配内存地址
2.初始化uni
3.把uni指向刚才分配的内存地址
由于jvm指令重排,上述步骤可能按照1 3 2的顺序执行,多线程环境下,执行完3就有调用方get到了uni,但是此时uni还没有被初始化。
volatile可以避免指令重排。
构造方法本身就是线程安全的
不需要用synchronized修饰。
synchronized底层原理
修饰同步语句块
每个对象中都内置了一个objectMonitor对象,获取锁就是获取对象监视器monitor的持有权。
monitorenter指向被synchronized修饰的同步语句块开始的位置,monitorexit指向同步语句块结束的位置。
当执行monitorenter时,会尝试获取对象的锁,如果锁的计数器为0表示可以获取,获取到后计数器会置为1。
monitorexit执行后,计数器会重新置为0。
修饰方法
被修饰的方法会用ACC_SYNCHRONIZED标识,表明该方法是同步方法。本质也是对monitor的获取。
以上是关于21 synchronized的主要内容,如果未能解决你的问题,请参考以下文章
#yyds干货盘点# Java | 关于synchronized相关理解
14.VisualVM使用详解15.VisualVM堆查看器使用的内存不足19.class文件--文件结构--魔数20.文件结构--常量池21.文件结构访问标志(2个字节)22.类加载机制概(代码片段