1.1、synchronized的性质
可重入:指的是同一个线程的外层函数获得锁后,内层函数可以直接再次获取该锁
好处:避免死锁,提升封装性
粒度:线程而非调用(用三种情况来说明和pthread的区别)
情况一:证明同一个方法是可重入的
package Synchronized.Three;
public class First {
int a = 0;
public static void main(String[] args){
First f = new First();
f.method1();
}
private synchronized void method1() {
System.out.println("This is method1:a = "+a);
if(a==0){
a++;
method1();
}
}
}
This is method1:a = 0
This is method1:a = 1
、、证明了同一方法的可重入性,method()方法获取了锁,所以可以递归执行。
情况二:证明可重入不要求是同一个方法
package Synchronized.Three;
public class Second {
public synchronized void method1(){
System.out.println("This is method1!");
method2();
}
public synchronized void method2(){
System.out.println("This is method2!");
}
public static void main(){
Second s = new Second();
s.method1();
}
}
This is method1!
This is method2!
情况三:证明可重入不要求是同一个类中
package Synchronized.Three;
public class three {
public synchronized void method(){
System.out.println("I'm father-method!");
}
}
class three_son extends three{
public synchronized void method(){
System.out.println("I'm son-method!");
super.method();
}
public static void main(String[] args) {
three_son ts=new three_son();
ts.method();
}
}
I’m son-method!
I’m father-method!
上述证明了Java中synchronized关键字粒度是线程范围内的,不是调度范围内的。
也就是说,在一个线程中,如果他已经拿到了一把锁,而且想再次使用这把锁去访问其他的方法,并且要访问的方法需要的锁,就是我手中的这把锁,那么就依据可重入性,不需要再次显式地释放锁,可以直接访问该方法。