美文网首页
synchronized关键字(二)

synchronized关键字(二)

作者: AD刘涛 | 来源:发表于2020-03-13 18:24 被阅读0次

可重入

指的是同一线程的外层函数获得锁之后,内层函数可以直接再次获取该锁。

怎么理解这段话呢?

举个通俗例子 --- 摇号。在这个故事中把摇到号比喻做线程获取到了锁。假设我家目前有3辆车,我想给我家3辆车都上牌照。问题是摇到一次号只能给一辆车上号,如果我想给3辆车上牌照,我需要摇3次号。这样的一种行为称作不可重入。反之,摇到一次号就可以一直上牌照,直到自己主动弃权,这样的一种行为则可称为可重入

有什么好处?

  1. 避免死锁
  2. 提升封装性(避免一次次的加锁,解锁)
  3. 粒度:针对线程而非调用(Linux中的phread的粒度则是针对调用层面)
    1. 证明同一个方式是可重入的
    package synchronize;
    
     /**
     * 描述:可重入粒度测试:递归调用本方法(证明同一个方
     * 式是可重入的)
     */
     public class SynchronizedRecursion10 {
         int a = 0;
    
         public static void main(String[] args) {
             SynchronizedRecursion10 synchronizedRecursion10 = new SynchronizedRecursion10();
             synchronizedRecursion10.method1();
    
         }
    
         private synchronized void method1() {
             System.out.println("这是methods方法, a=" + a);
             if (a == 0){
                 a++;
                 method1();
             }
         }
     }
    
    1. 证明可重入不要求是同一个方法
    package synchronize;
    
     /**
     * 描述:可重入粒度测试:调用类内另外的方法:证明可重入不要求是同一个方法
     */
     public class SynchronizedOtherMethod11 {
    
         public static void main(String[] args) {
             SynchronizedOtherMethod11 synchronizedOtherMethod11 = new SynchronizedOtherMethod11();
             synchronizedOtherMethod11.method1();
         }
    
         public synchronized void method1() {
             System.out.println("我是method1");
             method2();
         }
    
         public synchronized void method2() {
             System.out.println("我是method2");
         }
     }
    
    
    1. 证明可重入不要求是同一个类中的方法
    package synchronize;
    
     /**
     * 描述: 可重入粒度测试,调用父类方法
     */
     public class SynchronizedSuperclass12 {
         public synchronized void doSomething(){
             System.out.println("我是父类方法");
         }
     }
    
     class TestClass extends SynchronizedSuperclass12{
         public synchronized void doSomething(){
             System.out.println("我是子类方法");
             super.doSomething();
         }
    
         public static void main(String[] args) {
             TestClass s = new TestClass();
             s.doSomething();
         }
     }
    

不可中断

一旦这个锁已经被别人获得了,如果我还想获取,我只能选择等待或者阻塞,直到别的线程释放这个锁。如果别人永远不释放锁,那么我只能永远的等下去。

相比之下,未来会介绍Lock类,它可以拥有中断的能力。第一点,如果它觉得我等的时间太长,有权中断现在已经获取到锁的线程的执行;第二点:如果它觉得等待的时间太长了,不想再等了,也可以退出。

相关文章

网友评论

      本文标题:synchronized关键字(二)

      本文链接:https://www.haomeiwen.com/subject/irwsshtx.html