文档章节

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

© 著作权归作者所有

共有 人打赏支持
乐在克里特
粉丝 15
博文 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
Java多线程学习(二)synchronized关键字(2)

系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Ja...

一只蜗牛呀
04/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

day99-20180926-英语流利阅读-待学习

换汤不换药的美容大忽悠:从抗衰老到肌肤焕发新生 Lala 2018-09-26 1.今日导读 说到护肤品,一个个大牌广告就浮现在我们眼前:皮肤吹弹可破的女明星手捧功能各异的瓶瓶罐罐,暗示着消费者买买...

飞鱼说编程
35分钟前
3
0
FFmpeg Maintainer赵军:FFmpeg关键组件与硬件加速

大家好!我是赵军,现就职于英特尔的DCG从事基于FFmpeg的硬件优化工作,两年多前加入FFmpeg社区,2018年4月成为FFmpeg的其中的一个FFmpeg Maintainer,主要负责FFmpeg的硬件优化工作。 概览:...

yizhichao
今天
1
0
ehlib 修改 使行号字体颜色 与标题字体颜色 一致

对ehlib 显示效果不够满意,而做的调整 修改这个过程:procedure TCustomDBGridEh.DrawIndicatorCell(ACol, ARow: Longint; AreaCol, AreaRow: Longint; ARect: TRect; AState: TGri......

vga
今天
1
0
Bash重定向详解

Bash重定向详解 Bash的重定向指的是将命令的输入和输出导向不同地方,而不是默认的标准输入、标准输出和标准错误。Bash的重定向实际上是对标准输入、标准输出和标准错误的重置,进而将所需输...

小陶小陶
今天
3
0
EventBus原理深度解析

一、问题描述 在工作中,经常会遇见使用异步的方式来发送事件,或者触发另外一个动作:经常用到的框架是MQ(分布式方式通知)。如果是同一个jvm里面通知的话,就可以使用EventBus。由于Event...

yangjianzhou
今天
59
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部