005 锁的重入性 | 重入锁

2019-03-20  本文已影响0人  __destory__

重入锁

一个进程 获得到某个对象的锁后,在其他地方,又需要获得该对象的锁,此时,可以进入,而不是阻塞。

Java中ReentrantLock和synchronized都是可重入锁,可重入锁的一个优点是可一定程度避免死锁

重入的特性,发生在同一个线程本身,而且是获得锁后的时间内,再次需要获得锁,不阻塞,直接进入

public synchronized void a () {
    System.out.println("a");
    b();
    
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public synchronized void b() {
    System.out.println("b");
    
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
}

//main方法
Demo d1= new Demo();
new Thread(new Runnable() {
  @Override
  public void run() {
    d1.a();
  }
}).start();

上述,两个synchronized关键词,作用都是一个对象d1(确保是同一个锁了),a方法获得锁,在持有锁期间,需要获得b方法的锁(同一个锁),重入不阻塞。

看是否能够获得锁,需要明确是否是同一个对象的锁,以及是否可重入,如下,

public synchronized void a () {
    System.out.println("a");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public synchronized void b() {
    System.out.println("b");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

public static void main(String[] args) {
Demo d1= new Demo();
new Thread(new Runnable() {
    @Override
    public void run() {
        d1.a();
    }
}).start();
new Thread(new Runnable() {
    @Override
    public void run() {
        d1.b();
    }
}).start();
}

执行顺序(可能)先输出a,等待1秒后,输出b,为什么不是同时输出ab?
因为第一个线程先获得到锁后,对于第二个线程而言,因为是一个锁对象,所以等待,当第一个线程执行完毕后释放锁,第二个线程才能获得锁。可重入性针对是同一个线程而言,多个线程的情况,竞争获得锁

上一篇 下一篇

猜你喜欢

热点阅读