文档章节

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

乐在克里特
 乐在克里特
发布于 2017/02/23 13:53
字数 823
阅读 3
收藏 0

【问题描述】关于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

© 著作权归作者所有

共有 人打赏支持
乐在克里特
粉丝 16
博文 268
码字总数 394729
作品 0
杭州
程序员
私信 提问
java并发编程(2)——wait和notify解析

JAVA的进程同步是通过synchronized()来实现的,需要说明的是,JAVA的synchronized()方法类似于操作系统概念中的互斥内存块,在JAVA中的Object类型中,都是带有一个内存锁的,在有线程获取该内...

十二缸帕萨特
2014/04/12
0
0
简单的入门Android开发和Java语言基础[图]

简单的入门Android开发和Java语言基础[图] 前言: 去年年底到今年年初,我做过简单的智能家居,也实现过一些简单的直连和远程的智能家居。于是就将最简单的通信发布出来:智能家居简单实现—...

原创小博客
08/04
0
0
干货——详解Java中的关键字

在平时编码中,我们可能只注意了这些static,final,volatile等关键字的使用,忽略了他们的细节,更深层次的意义。 本文总结了Java中所有常见的关键字以及一些例子。 static 关键字 概述: ...

Janti
07/22
0
0
抽象类(接口)能被实例化吗?static、synchronized、native修饰抽象方法能行吗

答案是否定的,抽象类是不能直接被实例化的,不能直接通过new关键字来获取实例对象,有的人可能会说在new的时候实现接口方法或者抽象方法就能实例化了,就像这样 实际上呢,这并不是直接的实...

AI9o後
2017/11/03
0
0
10个经典的 Java main 方法面试题

以下是笔者认为比较经典的关于Java main方法的面试题,与其说是Java面试题,其实也是Java的一些最基础知识问题,分享给大家,如有错误,请指出。 很多小伙伴都喜欢在网上寻找教程,这种学习的...

紫魅编程
2016/04/23
379
0

没有更多内容

加载失败,请刷新页面

加载更多

Flink-数据流编程模型

1、抽象等级 Flink提供了不同级别的抽象来开发流/批处理应用程序。 1) 低层级的抽象 最低层次的抽象仅仅提供有状态流。它通过Process函数嵌入到DataStream API中。它允许用户自由地处理来自一...

liwei2000
24分钟前
1
0
Java开发Swing实战JFrame和JTabbedPane容器的用法详细解析

概述: 项目是一个桌面程序,涉及标签和按钮组件、布局管理器组件、面板组件、列表框和下拉框组件等组件,以及Swing事件处理机制。 下面先从最基础的界面开始。 /** * @author: lishuai * @...

金铭鼎IT教育
30分钟前
9
0
flask 之旅

环境 为了正确地跑起来,你的应用需要依赖许多不同的软件。 就算是再怎么否认这一点的人,也无法否认至少需要依赖Flask本身。 你的应用的运行环境,在当你想要让它跑起来时,是至关重要的。 ...

hblt-j
30分钟前
6
0
easyui的上传文件

记录一下自己亲手操刀easyui的心得:不用不知道,一用就问题多,网上查资料,有用的真的太少了 ——————————————————正文 FileBox,还是不错的讲真,至少我去自己写就gaga了...

anlve
31分钟前
4
0
如何做好SQLite 使用质量检测,让事故消灭在摇篮里

本文由云+社区发表 SQLite 在移动端开发中广泛使用,其使用质量直接影响到产品的体验。 常见的 SQLite 质量监控一般都是依赖上线后反馈的机制,比如耗时监控或者用户反馈。这种方式问题是: ...

腾讯云加社区
33分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部