一、synchronized的特性
(1)互斥性
synchronized 会起到互斥效果, 某个线程执⾏到某个对象的 synchronized 中时, 其他线程如果也执⾏到同⼀个对象 synchronized 就会阻塞等待.
• 进⼊ synchronized 修饰的代码块, 相当于 加锁
• 退出 synchronized 修饰的代码块, 相当于 解锁
synchronized void increase(){
count++;
}
第一个{:是进入方法内部,相当于针对当前对象“枷锁”
第二个{:执行完方法,相当于针对当前对象“解锁”
注意:
• 上⼀个线程解锁之后, 下⼀个线程并不是⽴即就能获取到锁. ⽽是要靠操作系统来 "唤醒". 这也就
是操作系统线程调度的⼀部分⼯作.
• 假设有 A B C 三个线程, 线程 A 先获取到锁, 然后 B 尝试获取锁, 然后 C 再尝试获取锁, 此时 B 和 C都在阻塞队列中排队等待. 但是当 A 释放锁之后, 虽然 B ⽐ C 先来的, 但是 B 不⼀定就能获取到锁,⽽是和 C 重新竞争,并不遵守先来后到的规则
(2)可重入性
synchronized同步块对同一线程是可重入的,不会出现自己把自己锁死的问题;
什么是将自己锁死
一个线程没有释放锁,然后又尝试再次加锁。
//第一次加锁,加锁成功
lock();
//第二次加锁,锁已被占用,阻塞等待
lock();
按照之前对于锁的设定, 第⼆次加锁的时候, 就会阻塞等待. 直到第⼀次的锁被释放, 才能获取到第⼆个锁. 但是释放第⼀个锁也是由该线程来完成, 结果这个线程已经躺平了, 啥都不想⼲了, 也就⽆法进⾏解锁操作. 这时候就会 死锁.
二、synchronized的使用
synchronized本质上要修改指定对象的“对象头”。从使用角度来看,sybchronized也势必要搭配一个具体的对象来使用。
(1)修饰代码块:明确指定锁哪个对象
1.锁任意对象
public class SynchronizedDemo{
private Object locker = new Object();
public void method(){
synchronized(locker){
}
}
}
2.锁当前对象
public class SynchronizedDemo{
public void method(){
synchronized(this){
}
}
}
(2)直接修饰普通方法:锁的SynchronizedDemo对象
public class SynchronizedDemo{
public synchronized void methond(){
}
}
(3)修饰静态方法:锁的SuynchronizedDemo类的对象
public class SynchronizedDemo{
public synchronized static void methond(){
}
}
1万+

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



