JAVA中的每个对象都可以用作一个实现同步的锁这种称为内置锁内置锁是可重入的因此如果某个线程试图获取一个已经由它自己持有的锁那么这个请求就会成功
重入的实现方法是为每个锁关联一个获取计数值和一个所有者线程当计数值为这个锁就是开放的当线程请求该锁时JVM将记下锁的持有者并且将计数值+如果同一个线程再次回去该锁计数值继续+通过计数值可以看出重入的次数计数值为则表示锁已经释放
看一个重入锁的实例
class Father {
public synchronized void doSth(){
Systemoutprintln(Father is doSth);
}
}
class Child extends Father {
public synchronized void doSth() {
Systemoutprintln(Child is doSth);
superdoSth();
}
}
class Father {
public synchronized void doSth(){
Systemoutprintln(Father is doSth);
}
}
class Child extends Father {
public synchronized void doSth() {
Systemoutprintln(Child is doSth);
superdoSth();
}
}
以上一段代码在执行Child类的superdoSth()方法时并不会发生死锁现象这两个类中的方法都是synchronized同步的因此执行前都会获取Father的锁正因为是可重入的才可以多次获取该锁不然第二次获取该锁时必然发生死锁现象
synchronized虽然提供了状态同步的功能加锁限制但是使用时一定要切记加锁代码块的大小否则会影响性能这种同步代码块的大小需要去权衡