21 synchronized

Posted cathy_mu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了21 synchronized相关的知识,希望对你有一定的参考价值。

synchronized
被他修饰的方法或代码块在任一时刻只有一个线程执行。

使用synchronized

  1. 修饰实例方法=对实例加锁,执行前需要获得实例的锁

    synchronized void method() {
      //业务代码
    }
  2. 修饰静态方法 = 对类加锁

    synchronized static void method() {
    //业务代码
    }
  3. 修饰代码块 = 给指定对象/类加锁

    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的主要内容,如果未能解决你的问题,请参考以下文章

synchronized学习

21个常用代码片段

同步代码 [重复]

#yyds干货盘点# Java | 关于synchronized相关理解

21 线程同步

14.VisualVM使用详解15.VisualVM堆查看器使用的内存不足19.class文件--文件结构--魔数20.文件结构--常量池21.文件结构访问标志(2个字节)22.类加载机制概(代码片段