Java中synchronized 修饰在static方法和非static方法的区别
【问题描述】关于Java中synchronized 用在实例方法和对象方法上面的区别
【问题分析】大家都知道,在Java中,synchronized 是用来表示同步的,我们可以synchronized 来修饰一个方法(实例方法和类方法---注:不知道这样叫准确不准确,大家理解我的意识就行了)。也可以synchronized 来修饰方法里面的一个语句块。
修饰实例方法:
- public synchronized void x() throws InterruptedException
- {
- ; i++)
- {
- );
- System.out.println("x.......................");
- }
- }
修饰类方法(static 方法):
- public static synchronized void staticX() throws InterruptedException
- {
- ; i++)
- {
- );
- System.out.println("staticX.......................");
- }
- }
修饰方法里面语句块:
- public static void staticX() throws InterruptedException
- {
- synchronized (locks)
- {
- ; i++)
- {
- );
- System.out.println("staticX.......................");
- }
- }
- }
注意:这里不能用synchronized修饰方法外面的语句块(我把他叫做类语句块),虽然我们可以在方法外面定义语句块,这样做会遇到编译错误,这里涉及到了Java里面的对象初始化的部分知识。大概的原因就是synchronized锁住的是对象,当初始化对象的时候,JVM在对象初始化完成之前会调用方法外面的语句块,这个时候对象还不存在,所以就不存在锁了。
那么,在static方法和非static方法前面加synchronized到底有什么不同呢?
大家都知道,static的方法属于类方法,它属于这个Class(注意:这里的Class不是指Class的某个具体对象),那么static获取到的锁,就是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。而非static方法获取到的锁,就是当前调用这个方法的对象的锁了。所以,他们之间不会产生互斥。
看代码:
- package com.jack.zhang.chapter9.classlock;
- /**
- * @author Jack Zhang
- * @version vb1.0
- * @Email virgoboy2004@163.com
- * @Date 2012-5-20
- */
- public class Test
- {
- public static synchronized void staticX() throws InterruptedException
- {
- ; i++)
- {
- );
- System.out.println("staticX.......................");
- }
- }
- public synchronized void x() throws InterruptedException
- {
- ; i++)
- {
- );
- System.out.println("x.......................");
- }
- }
- public static void main(String[] args)
- {
- final Test test1 = new Test();
- Thread thread = new Thread(new Runnable()
- {
- public void run()
- {
- try
- {
- test1.x();
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }, "a");
- Thread thread1 = new Thread(new Runnable()
- {
- public void run()
- {
- try
- {
- Test.staticX();
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }, "b");
- thread1.start();
- thread.start();
- }
- }
运行结果是:
- staticX.......................
- x.......................
- x.......................
- staticX.......................
- staticX.......................
- x.......................
- x.......................
- staticX.......................
- x.......................
- staticX.......................
- staticX.......................
- x.......................
- x.......................
- staticX.......................
- x.......................
- staticX.......................
- x.......................
- staticX.......................
- x.......................
- staticX.......................
那当我们想让所有这个类下面的对象都同步的时候,也就是让所有这个类下面的对象共用同一把锁的时候,我们如何办呢?
看代码:
- package com.jack.zhang.chapter9.classlock;
- /**
- * @author Jack Zhang
- * @version vb1.0
- * @Email virgoboy2004@163.com
- * @Date 2012-5-20
- */
- public class Test
- {
- ];
- public static void staticX() throws InterruptedException
- {
- synchronized (locks)
- {
- ; i++)
- {
- );
- System.out.println("staticX.......................");
- }
- }
- }
- public void x() throws InterruptedException
- {
- synchronized (locks)
- {
- ; i++)
- {
- );
- System.out.println("x.......................");
- }
- }
- }
- public static void main(String[] args)
- {
- final Test test1 = new Test();
- final Test test2 = new Test();
- Thread thread = new Thread(new Runnable()
- {
- public void run()
- {
- try
- {
- test1.x();
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }, "a");
- Thread thread1 = new Thread(new Runnable()
- {
- public void run()
- {
- try
- {
- Test.staticX();
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }, "b");
- thread1.start();
- thread.start();
- }
- }
运行结果:
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- x.......................
- x.......................
- x.......................
- x.......................
- x.......................
- x.......................
- x.......................
- x.......................
- x.......................
- x.......................
Java中synchronized 修饰在static方法和非static方法的区别的更多相关文章
- synchronized 修饰在 static方法和非static方法的区别
Java中synchronized用在静态方法和非静态方法上面的区别 在Java中,synchronized是用来表示同步的,我们可以synchronized来修饰一个方法.也可以synchroniz ...
- java——多线程——单例模式的static方法和非static方法是否是线程安全的?
单例模式的static方法和非static方法是否是线程安全的? 答案是:单例模式的static方法和非static方法是否是线程安全的,与单例模式无关.也就说,如果static方法或者非static ...
- static方法和非static方法的区别
●生命周期(Lifecycle):静态方法(Static Method)与静态成员变量一样,属于类本身,在类装载的时候被装载到内存(Memory),不自动进行销毁,会一直存在于内存中,直到JVM关闭. ...
- RequestDispatcher.forward() 方法和HttpServletResponse.sendRedirect()方法的区别
RequestDispatcher.forward() 方法和HttpServletResponse.sendRedirect()方法的区别 先贴一段代码 public void logon(Http ...
- java static成员变量方法和非static成员变量方法的区别
这里的普通方法和成员变量是指,非静态方法和非静态成员变量首先static是静态的意思,是修饰符,可以被用来修饰变量或者方法. static成员变量有全局变量的作用 非static成员变量则 ...
- Java中使用BufferedReader的readLine()方法和read()方法来读取文件内容
目标:读文件 编程时,有很多时候需要读取本地文件,下面介绍一下读取方式: 读单行文件 package com; import java.io.*; import java.util.ArrayList ...
- length属性,length()方法和size()的方法的区别
一.java 1.length属性是针对Java中的数组来说的,要求数组的长度可以用其length属性: 2.length()方法是针对字符串来说的,要求一个字符串的长度就要用到它的length()方 ...
- View inflate方法和LayoutInflater inflate方法的区别详解
原创文章,转载请注明出处:http://www.cnblogs.com/baipengzhan/p/6257510.html 我们在Android开发中,对于将布局填充成View对象,最常用的两种办法 ...
- length属性、length()方法和size()的方法的区别
JAVA 1. length属性是针对Java中的数组来说的,要求数组的长度可以用其length属性: 2.length()方法是针对字符串来说的,要求一个字符串的长度就要用到它的length()方法 ...
随机推荐
- 【ASE高级软件工程】Alpha 阶段 backend组 scrum1 记录
本次会议于11月4日,19:10 在微软北京西二号楼13478召开,持续40分钟. 与会人员:Haifeng Chen, Zhikai Chen, Hao Wang, Jia Ning 请假: Xin ...
- robotframework API 源码阅读笔记----robot.utils.asserts
http://robot-framework.readthedocs.io/en/latest/autodoc/robot.utils.html#robot.utils.asserts.assert_ ...
- 系统INIT 启动脚本的结构/etc/rc.d/init.d/*
- 系统调用system_call处理过程
原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 作者:严哲璟 linux的系 ...
- VisualVM监控远程主机
参考博客 https://blog.csdn.net/u010004317/article/details/82948040 https://blog.csdn.net/lienfeng6/artic ...
- 《深入学习Redis(2):持久化》笔记
参考 https://www.cnblogs.com/kismetv/p/9137897.html 一.高可用概述 提供正常服务:主从分离,快速容灾技术,数据容量的扩展.数据安全不会丢失. 持久 ...
- maven 配置自动本地/线上不同配置自动打包
工程结构:在resource下新建开发,线上不同文件夹存放不同配置文件 pom.xml配置文件 <!-- maven配置不同环境打包 --> <build> <plugi ...
- 前端每日实战:67# 视频演示如何用纯 CSS 创作单元素点阵 loader
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览.https://codepen.io/comehope/pen/YvBvBr 可交互视频 此视频是可以 ...
- BZOJ3227 [sdoi2008]红黑树
贪心什么的太神仙了( 老老实实dp于是就是沙茶题了 f[i][d][0/1]表示i个节点bh为d当前节点颜色白/黑[好好读题是真.. 转移一下然后就可以打表了( 由于我们发现这玩意很好卡有很好的性质( ...
- 学习加密(四)spring boot 使用RSA+AES混合加密,前后端传递参数加解密
学习加密(四)spring boot 使用RSA+AES混合加密,前后端传递参数加解密 技术标签: RSA AES RSA AES 混合加密 整合 前言: 为了提高安全性采用了RS ...