meituan到店事业群平台技术部,秋招火热进行中!
内推方式1:
点击链接看内推二维码,扫码投 简历 https://www.cnblogs.com/CATHY-MU/p/15102097.html
内推方式2:
登陆官网投递( https://campus.meituan.com/ )填写内推码( OYkaHKQ)
平台技术部校招咨询qq群 821133476
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的获取。
全部评论
(1) 回帖