美文网首页
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