Java多线程编程——可重入锁以及Synchronized的其他基本特性

1、Synchronized锁重入

      (1)关键字Synchronized拥有【锁重入】的功能:

                也就是在使用Synchronized的时候,当一个线程得到一个对象锁后,在该锁里执行代码的时候可以再次请求该对象的锁时可以再次得到该对象的锁。

      (2)当线程请求一个由其它线程持有的对象锁时,该线程会阻塞,而当线程请求由自己持有的对象锁时,如果该锁是重入锁,请求就会成功,否则阻塞。

      (3)一个简单的例子就是:在一个Synchronized修饰的方法或代码块的内部调用本类的其他Synchronized修饰的方法或代码块时,是永远可以得到锁的,示例代码A如下:

        

       执行结果:

       

       示例代码A向我们演示了,如何在一个已经被synchronized关键字修饰过的方法再去调用对象中其他被synchronized修饰的方法。

  (4)那么,为什么要引入可重入锁这种机制呢?

            我们上一篇文章中介绍了一个“对象一把锁,多个对象多把锁”,可重入锁的概念就是:自己可以获取自己的内部锁

            假如有1个线程T获得了对象A的锁,那么该线程T如果在未释放前再次请求该对象的锁时,如果没有可重入锁的机制,是不会获取到锁的,这样的话             就会出现死锁的情况。

            就如代码A体现的那样,线程T在执行到method1()内部的时候,由于该线程已经获取了该对象syncDubbo 的对象锁,当执行到调用method2() 的时候,会再次请求该对象的对象锁,如果没有可重入锁机制的话,由于该线程T还未释放在刚进入method1() 时获取的对象锁,当执行到调用method2() 的时候,就会出现死锁。

   (5)那么可重入锁到底有什么用呢?

             正如上述代码A和(4)中解释那样,最大的作用是避免死锁

             假如有一个场景:用户名和密码保存在本地txt文件中,则登录验证方法和更新密码方法都应该被加synchronized,那么当更新密码的时候需要验证密              码的合法性,所以需要调用验证方法,此时是可以调用的。

   (6)关于可重入锁的实现原理,是一个大论题,在这里篇幅有限不再学习,有兴趣可以移步至:http://www.cnblogs.com/pureEve/p/6421273.html 进行学习。

   (7)可重入锁的其他特性:父子可继承性

             可重入锁支持在父子类继承的环境中,示例代码如下:

             

2、Synchronized的其他特性

     (1)出现异常时,锁自动释放

               当一个线程执行的代码出现异常的时候,其所持有的锁会自动释放,示例如下:

               

               执行结果如下:

                

               可以看出,当执行代码报错的时候,程序不会再执行,即释放了锁。

     (2)将任意对象作为监视器

                

               执行结果:

               

       (3)单利模式-双重校验锁:

                 单例模式中有一个经典的实现就是:双重校验锁,其中就是用到了synchronized,实现代码如下:

                 

      双重锁检验需要将对象申明为violate,不然会因为指令重排序导致在第一个判空时将未初始化的对象返回

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值