重入锁
当一个进程 获得到某个对象的锁后,在其他地方,又需要获得该对象的锁,此时,可以进入,而不是阻塞。
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?
因为第一个线程先获得到锁后,对于第二个线程而言,因为是一个锁对象,所以等待,当第一个线程执行完毕后释放锁,第二个线程才能获得锁。可重入性针对是同一个线程而言,多个线程的情况,竞争获得锁
网友评论