synchronized的实现原理

138 阅读2分钟

「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」。

synchronized的实现原理与应用

简述synchronized

synchronized在多线程开发中地位非凡,在JDK1.6之前许多人会称它为重量级锁,但是在JDK1.6之后。为了减少获得锁和释放锁带来的性能消耗而引进的偏向锁和轻量级锁,以及对sychronized进行了各种优化后,synchronized不再浪费过多的性能。synchronized是悲观锁可重入锁

悲观锁:在多线程任务执行中,一旦有一线程获得某一资源,其他线程只能等待该线程释放对象的锁。也就是说悲观锁会阻塞其他线程的锁。

可重入锁:synchronized会自动获得上锁方法的内部资源的锁,不用重复的去尝试获得已经获得锁的内部锁。

synchronized锁的对象

synchronized锁的是对象,java中的每一个对象都可以获得锁

具体为下三种情况:

  1. 对于普通同步方法,锁当前同步对象。
  2. 对于静态同步方法,锁当前类class对象。
  3. 对于同步方法块,锁synchronized括号里加载的对象。
public class Thread_{
 	/** 1. 对于普通同步方法,锁当前同步对象。**/
  public synchronized void Menthod1(){
   System.out.println("普通同步方法"); 
  }
  /** 2. 对于静态同步方法,锁当前类class对象。**/
  public static synchronized void Menthod2(){
    System.out.println("静态同步方法"); 
  }
  /** 3. 对于同步方法块,锁synchronized括号里加载的对象。**/
  public void Method2(){ 
        synchronized (this){ 
           System.out.println("同步方法块"); 
        } 
    } 
    
 }

sychronized锁的实现原理

从JVM规范中可以看出JVM通过进入和退出Monitor对象来实现方法同步代码块同步

代码块同步是通过编译后的monitorenter和monitorexit指令实现的

monitorenter指令是编译后插入到同步代码块开始的位置。线程执行到该命令的时候会尝试获取该对象相关的monitor对象。即尝试获得该对象的锁

monitorexit指令是插入到方法结束后或者异常处

方法同步通过另一种方法实现的,但是也可以使用这两个指令来实现

每个对象都有对应的monitor对象,当某一个对象的monitor被持有的时候即为上锁状态