Java中synchronized 修饰在static方法和非static方法的区别

【问题描述】关于Java中synchronized 用在实例方法和对象方法上面的区别

【问题分析】大家都知道,在Java中,synchronized 是用来表示同步的,我们可以synchronized 来修饰一个方法(实例方法和类方法---注:不知道这样叫准确不准确,大家理解我的意识就行了)。也可以synchronized 来修饰方法里面的一个语句块。

修饰实例方法:

  1. public synchronized void x() throws InterruptedException  
  2.     {  
  3.         for (int i = 0; i < 10; i++)  
  4.         {  
  5.             Thread.sleep(1000);  
  6.             System.out.println("x.......................");  
  7.         }  
  8.     }  


修饰类方法(static 方法):

  1. public static synchronized void staticX() throws InterruptedException  
  2.     {  
  3.         for (int i = 0; i < 10; i++)  
  4.         {  
  5.             Thread.sleep(1000);  
  6.             System.out.println("staticX.......................");  
  7.         }  
  8.     }  


修饰方法里面语句块:

  1. public static void staticX() throws InterruptedException  
  2.     {  
  3.         synchronized (locks)  
  4.         {  
  5.             for (int i = 0; i < 10; i++)  
  6.             {  
  7.                 Thread.sleep(1000);  
  8.                 System.out.println("staticX.......................");  
  9.             }  
  10.         }  
  11.     }  

注意:这里不能用synchronized修饰方法外面的语句块(我把他叫做类语句块),虽然我们可以在方法外面定义语句块,这样做会遇到编译错误,这里涉及到了Java里面的对象初始化的部分知识。大概的原因就是synchronized锁住的是对象,当初始化对象的时候,JVM在对象初始化完成之前会调用方法外面的语句块,这个时候对象还不存在,所以就不存在锁了。

那么,在static方法和非static方法前面加synchronized到底有什么不同呢?

大家都知道,static的方法属于类方法,它属于这个Class(注意:这里的Class不是指Class的某个具体对象),那么static获取到的锁,就是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。而非static方法获取到的锁,就是当前调用这个方法的对象的锁了。所以,他们之间不会产生互斥。

看代码:

  1. package com.jack.zhang.chapter9.classlock;  
  2.   
  3. /** 
  4.  * @author Jack Zhang 
  5.  * @version vb1.0 
  6.  * @Email [email protected] 
  7.  * @Date 2012-5-20 
  8.  */  
  9. public class Test  
  10. {  
  11.     public static synchronized void staticX() throws InterruptedException  
  12.     {  
  13.         for (int i = 0; i < 10; i++)  
  14.         {  
  15.             Thread.sleep(1000);  
  16.             System.out.println("staticX.......................");  
  17.         }  
  18.     }  
  19.   
  20.     public synchronized void x() throws InterruptedException  
  21.     {  
  22.         for (int i = 0; i < 10; i++)  
  23.         {  
  24.             Thread.sleep(1000);  
  25.             System.out.println("x.......................");  
  26.         }  
  27.     }  
  28.   
  29.     public static void main(String[] args)  
  30.     {  
  31.         final Test test1 = new Test();  
  32.         Thread thread = new Thread(new Runnable()  
  33.         {  
  34.             public void run()  
  35.             {  
  36.                 try  
  37.                 {  
  38.                     test1.x();  
  39.                 }  
  40.                 catch (InterruptedException e)  
  41.                 {  
  42.                     // TODO Auto-generated catch block  
  43.                     e.printStackTrace();  
  44.                 }  
  45.             }  
  46.         }, "a");  
  47.   
  48.         Thread thread1 = new Thread(new Runnable()  
  49.         {  
  50.             public void run()  
  51.             {  
  52.                 try  
  53.                 {  
  54.                     Test.staticX();  
  55.                 }  
  56.                 catch (InterruptedException e)  
  57.                 {  
  58.                     // TODO Auto-generated catch block  
  59.                     e.printStackTrace();  
  60.                 }  
  61.             }  
  62.         }, "b");  
  63.   
  64.         thread1.start();  
  65.         thread.start();  
  66.     }  
  67. }  


运行结果是:

  1. staticX.......................  
  2. x.......................  
  3. x.......................  
  4. staticX.......................  
  5. staticX.......................  
  6. x.......................  
  7. x.......................  
  8. staticX.......................  
  9. x.......................  
  10. staticX.......................  
  11. staticX.......................  
  12. x.......................  
  13. x.......................  
  14. staticX.......................  
  15. x.......................  
  16. staticX.......................  
  17. x.......................  
  18. staticX.......................  
  19. x.......................  
  20. staticX.......................  



那当我们想让所有这个类下面的对象都同步的时候,也就是让所有这个类下面的对象共用同一把锁的时候,我们如何办呢?

看代码:

  1. package com.jack.zhang.chapter9.classlock;  
  2.   
  3.   
  4. /** 
  5.  * @author Jack Zhang 
  6.  * @version vb1.0 
  7.  * @Email [email protected] 
  8.  * @Date 2012-5-20 
  9.  */  
  10. public class Test  
  11. {  
  12.     public final static Byte[] locks = new Byte[0];  
  13.   
  14.     public static void staticX() throws InterruptedException  
  15.     {  
  16.         synchronized (locks)  
  17.         {  
  18.             for (int i = 0; i < 10; i++)  
  19.             {  
  20.                 Thread.sleep(1000);  
  21.                 System.out.println("staticX.......................");  
  22.             }  
  23.         }  
  24.     }  
  25.   
  26.     public void x() throws InterruptedException  
  27.     {  
  28.         synchronized (locks)  
  29.         {  
  30.             for (int i = 0; i < 10; i++)  
  31.             {  
  32.                 Thread.sleep(1000);  
  33.                 System.out.println("x.......................");  
  34.             }  
  35.         }  
  36.     }  
  37.   
  38.     public static void main(String[] args)  
  39.     {  
  40.         final Test test1 = new Test();  
  41.         final Test test2 = new Test();  
  42.         Thread thread = new Thread(new Runnable()  
  43.         {  
  44.             public void run()  
  45.             {  
  46.                 try  
  47.                 {  
  48.                     test1.x();  
  49.                 }  
  50.                 catch (InterruptedException e)  
  51.                 {  
  52.                     // TODO Auto-generated catch block  
  53.                     e.printStackTrace();  
  54.                 }  
  55.             }  
  56.         }, "a");  
  57.   
  58.         Thread thread1 = new Thread(new Runnable()  
  59.         {  
  60.             public void run()  
  61.             {  
  62.                 try  
  63.                 {  
  64.                     Test.staticX();  
  65.                 }  
  66.                 catch (InterruptedException e)  
  67.                 {  
  68.                     // TODO Auto-generated catch block  
  69.                     e.printStackTrace();  
  70.                 }  
  71.             }  
  72.         }, "b");  
  73.   
  74.         thread1.start();  
  75.         thread.start();  
  76.     }  
  77. }  


运行结果:

  1. staticX.......................  
  2. staticX.......................  
  3. staticX.......................  
  4. staticX.......................  
  5. staticX.......................  
  6. staticX.......................  
  7. staticX.......................  
  8. staticX.......................  
  9. staticX.......................  
  10. staticX.......................  
  11. x.......................  
  12. x.......................  
  13. x.......................  
  14. x.......................  
  15. x.......................  
  16. x.......................  
  17. x.......................  
  18. x.......................  
  19. x.......................  
  20. x.......................  

http://blog.csdn.net/virgoboy2004/article/details/7585182

猜你喜欢

转载自itommy.iteye.com/blog/2294392
今日推荐