1.Synchronized
1.1 加了synchronized的字节码指令和java源代码

synchronized(new Object()){ int a = 1;int b = 2; System.out.println(add(a,b)); }
由上图:被Synchronized修饰过的代码块,会生成monitorenter(监视器)字节码指令和monitorexit(监视器退出)字节码指令,当虚拟机执行到监视器指令的时候,就要去尝试去获取这个对象的锁,如果这个对象没有锁定,或者是当前线程已经获取了这个对象的锁(因为是可重入锁),就把锁的计数器+1,如果执行到监视器退出指令时候,就把锁的计数器-1。当计数器变为0的时候,就相当于这把锁被释放了,大家可以竞争。
1.2 Synchronized到底锁主了什么?
1.Synchronized(Object、this)这样指定了对象的锁的就是这个对象
2.在非静态方法上加上Synchronized相当于每个对象都有一把单独的锁
,假设创建对象p1,p2 如果p1执行了add方法占用了锁,但是占用的只是p1对象的锁,在另外一个线程中不影响p2继续执行add方法。
public synchronized int add(int a,int b)
3.在静态方法上加锁
相当于锁住了这个类,所有的实例共享一把锁,p1执行add方法占用了锁,在另外一个线程p2如果也想要add方法,执行同样需要等待
public synchronized static int add(int a,int b)
1.3可重入的特征
Synchronized是一个可重入锁,为了解决锁死自己的情况,来看示例:
Object o = new Object();
synchronized (o){ //计数器+1变为1
synchronized (o){//计数器+1变为2
System.out.println("执行么? ");
}//计数器-1变为1
}//计数器-1变为0 此时别的线程能够抢占
第一个synchronized已经占用到o这把锁了,第二个还能拿么,答案是可以的,不然很容易锁死。代码正常执行。
本文详细解析了Java中的synchronized关键字,包括其在字节码层面的表现,如何实现锁的获取与释放。synchronized可以锁定对象实例或类,对于非静态方法,每个对象拥有独立的锁,不同对象可以并行执行;而对于静态方法,锁住的是类,所有实例共享一把锁。此外,synchronized具备可重入特性,避免了死锁问题。示例代码展示了可重入锁的工作原理。

被折叠的 条评论
为什么被折叠?



