「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」。
synchronized的实现原理与应用
简述synchronized
synchronized在多线程开发中地位非凡,在JDK1.6之前许多人会称它为重量级锁,但是在JDK1.6之后。为了减少获得锁和释放锁带来的性能消耗而引进的偏向锁和轻量级锁,以及对sychronized进行了各种优化后,synchronized不再浪费过多的性能。synchronized是悲观锁和可重入锁。
悲观锁:在多线程任务执行中,一旦有一线程获得某一资源,其他线程只能等待该线程释放对象的锁。也就是说悲观锁会阻塞其他线程的锁。
可重入锁:synchronized会自动获得上锁方法的内部资源的锁,不用重复的去尝试获得已经获得锁的内部锁。
synchronized锁的对象
synchronized锁的是对象,java中的每一个对象都可以获得锁。
具体为下三种情况:
- 对于普通同步方法,锁当前同步对象。
- 对于静态同步方法,锁当前类class对象。
- 对于同步方法块,锁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被持有的时候即为上锁状态