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