一、死锁
死锁只可能发生在多重锁的情况下,单锁不会发生死锁,上代码:
public class Synchronized3Test {
.....
private void count(int newValue) {
synchronized (monitor1) {
x = newValue;
y = newValue;
synchronized (monitor2) {
name = "aaa";
}
}
}
....
private void setName(String newName) {
synchronized (monitor2) {
name = newName;
synchronized (monitor1) {
x = 0;
y = 1;
}
}
}
}
假如说业务需要在 count 时,先执行 x 、y ,再执行 name,在执行 setName 时,先执行 name,再执行 x 、y,恰好当前有两个个线程各自执行了 count 和 setName,这样 count 执行完 monitor1,执行 monitor2,发现有人在执行 monitor2,需要等待他被释放;同理 setName 执行 monitor2,需要执行 monitor1 时发现他也被占用了,需要等待释放,这样就互相等,一直等到天荒地老,,,,
这样就发生了死锁
二、乐观锁
他是一种乐观并发控制,并没有上锁,有人将其称为乐观锁
出现的场景:在数据库中,读出一个数据,对这个数据进行运算操作,然后将此数据写回到数据库中,假如说在读出和写回期间,有人修改了这条数据,如果我们之间将结果写回的话,那么就肯定不准确了,只能再读出来再运算后写回去
我们判定这种情况不会经常出现,采用以上乐观的方式去处理这个问题,提高性能,这种情况我们称之为乐观并发控制
三、悲观锁
放弃性能,在读之前就上锁,然后读,计算,再写回,解除锁
乐观锁和悲观锁是数据库设计相关,不是线程问题
四、静态的 synchronized 使用
参见 单例模式