首页 > 代码库 > 架构师养成记--3.synchronized细节问题

架构师养成记--3.synchronized细节问题

一、synchronized有锁重入的特点,某个线程得到对象的锁后,再次请求此对象可以再次得到改对象的锁。如下示例,在method1中调用method2,在method2中调用method3,而method1、method2和method3都是加了synchronized关键字的。

 1 /**
 2  * synchronized的重入
 3  * @author alienware
 4  *
 5  */
 6 public class SyncDubbo1 {
 7 
 8     public synchronized void method1(){
 9         System.out.println("method1..");
10         method2();
11     }
12     public synchronized void method2(){
13         System.out.println("method2..");
14         method3();
15     }
16     public synchronized void method3(){
17         System.out.println("method3..");
18     }
19     
20     public static void main(String[] args) {
21         final SyncDubbo1 sd = new SyncDubbo1();
22         Thread t1 = new Thread(new Runnable() {
23             @Override
24             public void run() {
25                 sd.method1();
26             }
27         });
28         t1.start();
29     }
30 }

二、父类和子类的方法都是synchronized的,在子类的方法中调用父类的方法,也是线程安全的。

 1 /**
 2  * synchronized的重入
 3  * @author alienware
 4  *
 5  */
 6 public class SyncDubbo2 {
 7 
 8     static class Main {
 9         public int i = 10;
10         public synchronized void operationSup(){
11             try {
12                 i--;
13                 System.out.println("Main print i = " + i);
14                 Thread.sleep(100);
15             } catch (InterruptedException e) {
16                 e.printStackTrace();
17             }
18         }
19     }
20     
21     static class Sub extends Main {
22         public synchronized void operationSub(){
23             try {
24                 while(i > 0) {
25                     i--;
26                     System.out.println("Sub print i = " + i);
27                     Thread.sleep(100);        
28                     this.operationSup();
29                 }
30             } catch (InterruptedException e) {
31                 e.printStackTrace();
32             }
33         }
34     }
35     
36     public static void main(String[] args) {
37         
38         Thread t1 = new Thread(new Runnable() {
39             @Override
40             public void run() {
41                 Sub sub = new Sub();
42                 sub.operationSub();
43             }
44         });
45         
46         t1.start();
47     }
48     
49     
50 }

执行结果:

 技术分享

三、synchronized方法内抛异常怎么处理

  throw RuntimeException打断此线程或者记录日志然后continue,选择哪种方案取决于具体业务要求。

 

 1 /**
 2  * synchronized异常
 3  * @author alienware
 4  *
 5  */
 6 public class SyncException {
 7 
 8     private int i = 0;
 9     public synchronized void operation(){
10         while(true){
11             try {
12                 i++;
13                 Thread.sleep(100);
14                 System.out.println(Thread.currentThread().getName() + " , i = " + i);
15                 if(i == 20){
16                     //Integer.parseInt("a");
17                     throw new RuntimeException();
18                 }
19             } catch (InterruptedException e) {
20                 e.printStackTrace();
21             }
22         }
23     }
24     
25     public static void main(String[] args) {
26         
27         final SyncException se = new SyncException();
28         Thread t1 = new Thread(new Runnable() {
29             @Override
30             public void run() {
31                 se.operation();
32             }
33         },"t1");
34         t1.start();
35     }
36     
37     
38 }

 

架构师养成记--3.synchronized细节问题