文档章节

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

乐在克里特
 乐在克里特
发布于 2017/02/23 13:53
字数 823
阅读 3
收藏 0
点赞 0
评论 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
抽象类(接口)能被实例化吗?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
115个Java面试题及回答

解释下可用的线程状态. 在执行期间, 线程会处于以下状态中的一种: Runnable: 线程已准备就绪, 但没有立即运行. Running: 处理器正在执行的线程代码. Waiting: 处于阻塞状态的线程, 等待外部某...

Yamazaki
2014/04/25
0
0
java final和static用法总结

Java关键字final、static使用总结 一、final 根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理...

艾柯
2014/03/12
0
0
synchronized与static synchronized 的区别

最近做java多线程开发处理中发现synchronized的使用还是有一些细节问题要注意的。 1.synchronized与static synchronized 的区别 synchronized是对类的当前实例进行加锁,防止其他线程同时访问...

断桥是否下过雪
2013/12/14
0
0
java基础一(第一个java程序、数据类型、访问控制、static、)

一、第一个java程序 public class HelloWord {//public访问修饰符 class关键字,声明为类 HelloWord类名 //public访问修饰符 static关键字 void表示无返回值 main程序入口 } 二、数据类型 Ja...

废柴
02/11
0
0
JAVA程序员面试题整理(较全面)

以下是在面试中可能会遇到的问题,话不多说,往下看 1、面向对象的特征有哪些方面? 2、访问修饰符public,private,protected,以及不写(默认)时的区别? 3、String 是最基本的数据类型吗? ...

编程大侠
04/09
0
0
Java Thread及其synchronized,wait,sleep,join,yeid,interrupt

Java SE7 API - Thread: http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield%28%29 参考资料:http://blog.csdn.net/lqqmisslll/article/details/54208491 一、线程的简......

YuanyuanL
2015/08/12
0
0
JAVA final finally finalize区别

简单区别: 中等区别: 虽然这三个单词在Java中都存在,但是并没有太多关联: final:java中的关键字,修饰符。 1.如果一个类被声明为final,就意味着它不能再派生出新的子类,不能作为父类被...

qq22734179
2014/03/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

流利阅读笔记28-20180717待学习

“我不干了!” 英国脱欧大臣递交辞呈 雪梨 2018-07-17 1.今日导读 7 月 6 日,英国政府高官齐聚英国首相的官方乡间别墅——契克斯庄园,讨论起草了一份关于英国政府脱欧立场的白皮书。可是没...

aibinxiao
29分钟前
2
0
OSChina 周二乱弹 —— 理解超算排名这个事,竟然超出了很多人的智商

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @-冰冰棒- :分享Ed Sheeran/Beyoncé的单曲《Perfect Duet (with Beyoncé)》 《Perfect Duet (with Beyoncé)》- Ed Sheeran/Beyoncé 手机...

小小编辑
39分钟前
25
5
Android 获取各大音乐平台的真实下载地址

废话 电脑使用谷歌浏览器或者QQ浏览器的时候。。。。。。。说不清楚,还是看图吧 大概意思就是,只要网页上需要播放,只要能播放并且开始播放,这个过程就肯定会请求到相关的音乐资源,然后就...

她叫我小渝
今天
0
0
shell中的函数、shell中的数组、告警系统需求分析

shell中的函数 格式: 格式: function f_name() { command } 函数必须要放在最前面 示例1(用来打印参数) 示例2(用于定义加法) 示例3(用于显示IP) shell中的数组 shell中的数组1 定义数...

Zhouliang6
今天
2
0
用 Scikit-Learn 和 Pandas 学习线性回归

      对于想深入了解线性回归的童鞋,这里给出一个完整的例子,详细学完这个例子,对用scikit-learn来运行线性回归,评估模型不会有什么问题了。 1. 获取数据,定义问题     没有...

wangxuwei
今天
1
0
MAC安装MAVEN

一:下载maven压缩包(Zip或tar可选),解压压缩包 二:打开终端输入:vim ~/.bash_profile(如果找不到该文件新建一个:touch ./bash_profile) 三:输入i 四:输入maven环境变量配置 MAVEN_HO...

WALK_MAN
今天
0
0
33.iptables备份与恢复 firewalld的9个zone以及操作 service的操作

10.19 iptables规则备份和恢复 10.20 firewalld的9个zone 10.21 firewalld关于zone的操作 10.22 firewalld关于service的操作 10.19 iptables规则备份和恢复: ~1. 保存和备份iptables规则 ~2...

王鑫linux
今天
2
0
大数据教程(2.11):keeperalived+nginx高可用集群搭建教程

上一章节博主为大家介绍了目前大型互联网项目的系统架构体系,相信大家应该注意到其中很重要的一块知识nginx技术,在本节博主将为大家分享nginx的相关技术以及配置过程。 一、nginx相关概念 ...

em_aaron
今天
1
0
Apache Directory Studio连接Weblogic内置LDAP

OBIEE默认使用Weblogic内置LDAP管理用户及组。 要整理已存在的用户及组,此前办法是导出安全数据,文本编辑器打开认证文件,使用正则表达式获取用户及组的信息。 后来想到直接用Apache Dire...

wffger
今天
2
0
HFS

FS,它是一种上传文件的软件。 专为个人用户所设计的 HTTP 档案系统 - Http File Server,如果您觉得架设 FTP Server 太麻烦,那么这个软件可以提供您更方便的档案传输系统,下载后无须安装,...

garkey
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部