为什么下面的代码不会导致死锁?我的意思是在我调用getNumber(.)后,类Test的对象应该被锁定,所以我不能访问getNumber2(.).
class Test() {
synchronized int getNumber(int i){
return getNumber2(i);
}
synchronized int getNumber2(int i) {
return i;
}
public static void main(String[] args) {
System.out.println((new Test()).getNumber(100));
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
100
Run Code Online (Sandbox Code Playgroud)
NPE*_*NPE 19
这是因为锁是重入的,这意味着它可以被同一个线程多次获取.
从Java教程:
可重入同步
回想一下,线程无法获取另一个线程拥有的锁.但是一个线程可以获得它已经拥有的锁.允许线程多次获取相同的锁可启用重入同步.这描述了一种情况,其中同步代码直接或间接地调用也包含同步代码的方法,并且两组代码使用相同的锁.在没有可重入同步的情况下,同步代码必须采取许多额外的预防措施,以避免线程导致自身阻塞.
JLS的相关部分是§17.1.同步:
Java编程语言为线程之间的通信提供了多种机制.这些方法中最基本的是同步,它是使用监视器实现的.Java中的每个对象都与一个监视器相关联,一个线程可以锁定或解锁.一次只有一个线程可以锁定监视器.尝试锁定该监视器的任何其他线程都将被阻止,直到它们可以获得该监视器上的锁定为止.线程t可以多次锁定特定监视器; 每次解锁都会逆转一次锁定操作的效果.
| 归档时间: |
|
| 查看次数: |
5294 次 |
| 最近记录: |