当某个线程请求一个由其余线程持有的锁时,发出请求的线程就会阻塞。然而,因为内置锁是可重入的,所以若是摸个线程试图得到一个已经由它本身持有的锁,那么这个请求就会成功。“重入”意味着获取锁的操做的粒度是“线程”,而不是调用。重入的一种实现方法是,为每一个锁关联一个获取计数值和一个全部者线程。当计数值为0时,这个锁就被认为是没有被任何线程所持有,当线程请求一个未被持有的锁时,JVM将记下锁的持有者,而且将获取计数值置为1,若是同一个线程再次获取这个锁,计数值将递增,而当线程退出同步代码块时,计数器会相应地递减。当计数值为0时,这个锁将被释放。sql
重入进一步提高了加锁行为的封装性,所以简化了面向对象并发代码的开发。分析以下程序:架构
public class Father { public synchronized void doSomething(){ ...... } } public class Child extends Father { public synchronized void doSomething(){ ...... super.doSomething(); } }
子类覆写了父类的同步方法,而后调用父类中的方法,此时若是没有可重入的锁,那么这段代码件产生死锁。并发
因为Fither和Child中的doSomething方法都是synchronized方法,所以每一个doSomething方法在执行前都会获取Child对象实例上的锁。若是内置锁不是可重入的,那么在调用super.doSomething时将没法得到该Child对象上的互斥锁,由于这个锁已经被持有,从而线程会永远阻塞下去,一直在等待一个永远也没法获取的锁。重入则避免了这种死锁状况的发生。分布式
同一个线程在调用本类中其余synchronized方法/块或父类中的synchronized方法/块时,都不会阻碍该线程地执行,由于互斥锁时可重入的。高并发
欢迎工做一到五年的Java工程师朋友们加入Java架构开发
: 867748702
群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、
Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,
Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)
合理利用本身每一分每一秒的时间来学习提高本身,
不要再用"没有时间“来掩饰本身思想上的懒惰!趁年轻,使劲拼,给将来的本身一个交代!性能