java可重入锁

2018-06-05  本文已影响0人  xtsylc

可重入概念:

   一个线程去请求其他线程所持有的锁时,发出请求的线程就会发生阻塞。

   如果一个线程试图去请求一个已经由他自己持有的锁的时,并且该锁是可重入的,则请求就会成功。

   重入意味着获取锁的粒度是线程,而不是调用。重入避免了一些死锁情况的发生。

java的可重入锁:

   synchronized:可重入锁;

   java.util.concurrent.locks.ReentrantLock:可重入锁;

可重入锁的一种实现方式:

   每个锁关联一个计数器和一个持有者对象。计数器为0,则该锁没有被持有。

   如果某个线程请求一个空闲锁,则jvm记录锁的持有者,并且将计数器置为1。

   该线程再次请求获得该锁时,计数器加一。

   当线程释放一次锁,计数器减一,直到计数器为0,则最终释放锁。

可重入锁的两种使用例子:

例子1:

   public class Example {
         public synchronized void lock1() {
                System.out.println("进入lock1");
          }

          public synchronized void lock2() {
                System.out.println("进入lock2");
                 lock1();
           }

          public static void main(String[] args) {
                new Example().lock2();
           }
     }

例子2:

   public class Widget {
         public synchronized void dosomething() {
                System.out.println("widget do something");
          }
    }
   public class LoggerWidget extends Widget {
         public synchronized void dosomething() {
               System.out.println("LoggerWidget do something");
               super.dosomething();
         }
        public static void main(String[] args) {
              new LoggerWidget().dosomething();
        }
   }

例子1说明:

   例子1很好理解,同一个实例的两个方法,可重入显然获得的是同一个对象。

例子2说明:

   该例子可能会有疑惑。

   当线程调用LoggerWidget的dosomething方法的时候,取得LoggerWidget对象锁。

   方法中调用super.dosomething方法,调用者依然是当前对象,即LoggerWidget对象。因此进入
   super.dosomething方法获得锁依然是LoggerWidget对象锁,这里体现了锁的可重入性。

总结:

  对于java锁来说,锁的持有者是线程,锁本身可以认为是对象。
上一篇 下一篇

猜你喜欢

热点阅读