可重入性(Reentrant Lock)
Java 中的固有锁(intrinsic lock)具有可重入性(Reentrancy),这意味着锁的获取是以每个线程(per-thread)为单位的,而不是每个调用(per-invocation)。
可重入性通过为每个锁关联一个占用计数和当前拥有进程。当计数为 0 时,锁未被持有。
当一个线程获得了一个未被持有的锁时,JVM 会记录锁当前的主人为这个线程,并且将锁的计数+1。
当同样的线程再次申请获得锁时,锁计数会再+1。而当拥有锁的线程退出 synchronized
块时,锁计数-1。最终,当锁计数到达 0 时,锁被释放。
锁的可重入性避免了在某种情况下的死锁(deadlock)。
public class Widget {
public synchronized void doSomething() {
...
}
}
public class LoggingWidget extends Widget {
public synchronized void doSomething() {
System.out.println(toString() + ": calling doSomething");
super.doSomething();
}
}
比如,在上面例子中,在一个 synchronized 方法中又调用了另一个 synchronized 方法。如果固有锁不具有可重性,super.doSomething();
的调用永远不会进入,因为在调用 LoggingWidget 对象的 doSomething() 时,LoggingWidget 类占用锁,因而 LoggingWidget 类的子类 Widget 类无法占用锁, 最终无法进入 Widget 类的 doSomethings()。本质是因为产生了死锁。
FEATURED TAGS
algorithm
algorithmproblem
architecturalpattern
architecture
aws
c#
cachesystem
codis
compile
concurrentcontrol
database
dataformat
datastructure
debug
design
designpattern
distributedsystem
django
docker
domain
engineering
freebsd
git
golang
grafana
hackintosh
hadoop
hardware
hexo
http
hugo
ios
iot
java
javaee
javascript
kafka
kubernetes
linux
linuxcommand
linuxio
lock
macos
markdown
microservices
mysql
nas
network
networkprogramming
nginx
node.js
npm
oop
openwrt
operatingsystem
padavan
performance
programming
prometheus
protobuf
python
redis
router
security
shell
software testing
spring
sql
systemdesign
truenas
ubuntu
vmware
vpn
windows
wmware
wordpress
xml
zookeeper