? 作者:小胡_不糊涂
🌱 作者主页:小胡_不糊涂的个人主页
📀 收录专栏:JavaEE
💖 持续更文,关注博主少走弯路,谢谢大家支持 💖
synchronized 会起到互斥效果,某个线程执?到某个对象的 synchronized 中时,其他线程如果也执?到同?个对象synchronized 就会阻塞等待。
synchronized?的锁是存在Java对象头?的。可以粗略理解成,每个对象在内存中存储的时候,都存有?块内存表?当前的 “锁定” 状态(类似于厕所的 “有?/??”)。
如果当前是 “??” 状态,那么就可以使?,使?时需要设为 “有?” 状态;如果当前是"有?"状态,那么其他??法使?,只能排队。
针对每?把锁,操作系统内部都维护了?个等待队列。当这个锁被某个线程占有的时候,其他线程尝试进?加锁,就加不上了,就会阻塞等待,?直等到之前的线程解锁之后,由操作系统唤醒?个新的线程,再来获取到这个锁。
注意:
synchronized 同步块对同?条线程来说是可重?的,不会出现??把??锁死的问题。
什么情况下,会把自己锁死?
?个线程没有释放锁,然后?尝试再次加锁。
// 第?次加锁,加锁成功
// 第?次加锁,锁已经被占?,阻塞等待。
按照之前对于锁的设定,第?次加锁的时候,就会阻塞等待。直到第?次的锁被释放,才能获取到第?个锁。
但是释放第?个锁也是由该线程来完成,结果这个线程已经躺平了,啥都不想?了,也就?法进?解锁操作。这时候就会 死锁,这样的锁也就称为 不可重入锁。
在可重?锁的内部, 包含了 “线程持有者” 和 “计数器” 两个信息。
synchronized 本质上要修改指定对象的 “对象头”。从使??度来看,synchronized 也势必要搭配?个具体的对象来使?。
明确指定锁哪个对象
//锁任意对象
public class SynchronizedDemo {
private Object locker = new Object();
public void method() {
synchronized (locker) {
}
}
}
//锁当前对象
public class SynchronizedDemo {
public void method() {
synchronized (this) {
}
}
}
锁的 SynchronizedDemo 对象
public class SynchronizedDemo {
public synchronized void methond() {
}
}
锁的 SynchronizedDemo 类的对象
public class SynchronizedDemo {
public synchronized static void method() {
}
}
两个线程竞争同?把锁,才会产?阻塞等待。
两个线程分别尝试获取两把不同的锁,不会产?竞争。