synchronized锁重入
- package synLockIn_1;
- /* synchronized锁重入,当一个线程得到一个对象锁且还未释放锁时,再次请求此对象锁时可以再次得到该对象的锁
- * 此例中线程1进入Service类的service_1方式时,得到了Lock锁,在这个方法内便可以再次访问service_2方法
- * 而此时由于对象锁没被释放,线程2无法访问service_1方法*/
- class Service{
- synchronized public void service1(){
- System.out.println(Thread.currentThread().getName()+" service_1");
- try{
- Thread.sleep(1000);
- }catch(InterruptedException ie){
- ie.printStackTrace();
- }
- service2();
- }
- synchronized public void service2(){
- System.out.println(Thread.currentThread().getName()+" service_2");
- try{
- Thread.sleep(1000);
- }catch(InterruptedException ie){
- ie.printStackTrace();
- }
- service3();
- }
- synchronized public void service3(){
- System.out.println(Thread.currentThread().getName()+" service_3");
- try{
- Thread.sleep(1000);
- }catch(InterruptedException ie){
- ie.printStackTrace();
- }
- }
- }
- class MyThread extends Thread{
- Service service;
- public MyThread(Service service){
- this.service = service;
- }
- @Override
- public void run(){
- service.service1();
- }
- }
- public class Run {
- public static void main(String[] args) {
- Service service = new Service(); //两个线程共享同一个Service对象,使得两个线程访问一个对象,JVM只产生一个对象锁
- MyThread t = new MyThread(service);
- t.start();
- MyThread t1 = new MyThread(service);
- t1.start();
- }
- }
运行结果如下

从运行结果中可以看出线程Thread-1先访问了service_1同步方法,输出Thread-1 service_1后停留1秒。对象锁还没释放,且两个线程共享同一个类,所以线程Thread-0无法访问service_1方法。而Thread-1还没释放对象锁,但可以重新获得对象锁继续访问service_2同步方法。
可重入锁也支持在父子类继承的环境中。
- package synLockIn2;
- /* synchronized锁重入,当一个线程得到一个对象锁且还未释放锁时,再次请求此对象锁时可以再次得到该对象的锁 */
- class Main {
- public int i = 10;
- synchronized public void operateIMainMethod(){
- try{
- System.out.println( Thread.currentThread().getName()+" main print i="+i);
- i--;
- Thread.sleep(100);
- }catch(InterruptedException ie){
- ie.printStackTrace();
- }
- }
- }
- class Sub extends Main {
- synchronized public void operateIMainMethod(){
- System.out.println(Thread.currentThread().getName()+" 线程开始!!");
- try{
- while( i > 0 ){
- System.out.println( Thread.currentThread().getName()+" sub print i=" + i);
- i--;
- Thread.sleep(100);
- super.operateIMainMethod();
- }
- }catch(InterruptedException ie){
- ie.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName()+" 线程结束!!");
- }
- }
- class MyThread extends Thread{
- Sub sub = new Sub();
- MyThread(Sub sub){
- this.sub = sub;
- }
- @Override
- public void run(){
- sub.operateIMainMethod();
- }
- }
- public class Run {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- Sub sub = new Sub();
- MyThread t = new MyThread(sub);
- t.start();
- MyThread t1 = new MyThread(sub);
- t1.start();
- }
- }
运行结果如下:

从结果可以看出线程Thread-0先访问子类的同步方法operateIMainMethod,输入Thread-0 sub print i=10,然后在还未释放对象锁的情况下重新获得对象锁访问父类的同步方法operateIMainMethod,输出Thread-0 main print i=9,然后进入下一个循环。
线程Thread-0访问结束释放对象锁后,线程Thread-1开始访问。由于共享同一个对象且i在同步方法operateIMainMethod()外被定义,所以当线程Thread-1访问时i已经为零。
synchronized锁重入的更多相关文章
- 深入理解Java中的synchronized锁重入
问题导入:如果一个线程调用了一个对象的同步方法,那么他还能不能在调用这个对象的另外一个同步方法呢? 这里就是synchronized锁重入问题. 一.synchronized锁重入 来看下面的代码: ...
- 5.synchronized锁重入
package demo1; /** * synchronized锁重入 * Created by liudan on 2017/6/5. */ public class MyThread5_sync ...
- Java 学习笔记之 Synchronized锁重入
Synchronized锁重入: 当一个线程得到一个对象锁后,再次请求此对象锁时是可以再次得到该对象的锁.这也证明在一个Synchronized方法/块的内部调用本类的其他Synchronized方法 ...
- Java并发编程原理与实战十一:锁重入&自旋锁&死锁
一.锁重入 package com.roocon.thread.t6; public class Demo { /* 当第一个线程A拿到当前实例锁后,进入a方法,那么,线程A还能拿到被当前实例所加锁的 ...
- synchronized的重入
/** * synchronized的重入 * */ public class SyncDubbo1 { public synchronized void method1(){ System.out. ...
- 浅谈Java中的锁:Synchronized、重入锁、读写锁
Java开发必须要掌握的知识点就包括如何使用锁在多线程的环境下控制对资源的访问限制 ◆ Synchronized ◆ 首先我们来看一段简单的代码: 12345678910111213141516171 ...
- java的synchronized可重入锁
在java内部,同一线程在调用自己类中其他synchronized方法/块或调用父类的synchronized方法/块都不会阻碍该线程的执行,就是说同一线程对同一个对象锁是可重入的,而且同一个线程可以 ...
- Synchronized可重入锁通俗易懂的简单分析
可重入锁概念: 当一个线程得到一个对象锁后,再次请求此对象时时可以再次得到该对象的锁的,这也证明synchronized方法/块的内部调用本类的其他synchronized方法/块时,时永远可以得到锁 ...
- Synchronized可重入锁分析
可重入锁又称递归锁,是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提是锁对象必须是同一对象或者class), 不会因为之前已经获取过还没实方而发生阻塞.即同一线程可执行 ...
随机推荐
- how to use ldid
1.进入管理员权限 sudo -s 2.赋予app运行权限 chmod -R 777 cellmap.app 3.查看app权限 ldid -e cellmap.app/cellmap 4.打开窗口 ...
- mybatis 与 日志
如上图所示,mybatis默认支持7种日志记录的方式,也可以自己实现Log接口,然后将实现类通过LogFactory注入到日志工厂中. LogFactory是日志模块的入口,外层通过getLog获取L ...
- 新增了个job
https://112.124.41.113/svn/wbhpro/wbh-adapter-job
- 6个强大的AngularJS扩展应用
本文链接:http://www.codeceo.com/article/6-angularjs-extension.html本文作者:码农网 – 小峰 AngularJS现在非常热门,是Google推 ...
- Tomcat部署Solr4.10.4
前段时间学习solr,兴致勃勃的从官网下载到solr5.3.0最新版本,然后在后期部署时出现了很多问题.首先,4.0到5.0是个大版本更新,下载 的压缩包的文件结构有了很多变化,导致网上很多关于sol ...
- SQL分页语句
有关分页 SQL 的资料很多,有的使用存储过程,有的使用游标.本人不喜欢使用游标,我觉得它耗资.效率低:使用存储过程是个不错的选择,因为存储过程是经过预编译的,执行效率高,也更灵活.先看看单条 SQL ...
- uml和模式01
// */ // ]]> uml和模式01 1. UML 2. 用例图 3. 用例和类的关系 4. 类图 1 UML 模型语言(Modeling Language 检查ML)是一种设计语言,人们 ...
- MSSTDFMT.DLL无法注册的解决
今天在使用Windows8的时候,发现了一个问题,当我想执行某个xxx.exe文件的时候,报的问题是MSSTDFMT.DLL无法注册. 但是我的系统又是64位的,那么可以这样操作: 从网上下载一个ms ...
- mysql 数据库视图迁移
最近做一个项目,为了方便查询,建了好多的视图表,正式上线的时候需要把本地数据库迁移到服务器上. 按照常规方法: 1."导出sql","导入sql",发现视图没过 ...
- oracle基础备份和还原
#全库备份 buffer inctype=complete file=c:\mminfo.dmp log=c:\mminfo.log #用户备份:用户mminfo下的所有表 buffer owner= ...