• 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 virgoboy2004@163.com 
    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 virgoboy2004@163.com 
    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

  • 相关阅读:
    docker安装kibana
    docker 安装elasticsearch
    redis常用命令
    判断CheckBox,select是否被选中
    里面的div怎么撑开外面的div,让高度自适应
    超链接,表单jquery提交方式
    SSM框架的sql中参数注入(#和$的区别)
    springmvc接收值的方式
    mysql语法顺序
    js创建对象并赋值其属性
  • 原文地址:https://www.cnblogs.com/itommy/p/10610475.html
Copyright © 2020-2023  润新知