什么叫可重入锁
可重入性:就是一个线程不用释放,可以重复的获取一个锁n次,只是在释放的时候,也需要相应的释放n次。(简单来说:A线程在某上下文中或得了某锁,当A线程想要在次获取该锁时,不会应为锁已经被自己占用,而需要先等到锁的释放)假使A线程即获得了锁,又在等待锁的释放,就会造成死锁。
注意:synchronized和reentrantlock都是可重入锁
synchronized:
无需释放锁,synchronized会自动释放锁
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
synchronized (this) {
System.out.println("第1次获取锁,这个锁是:" + this);
int index = 1;
while (true) {
synchronized (this) {
System.out.println("第" + (++index) + "次获取锁,这个锁是:" + this);
}
if (index == 10) {
break;
}
}
}
}
}).start();
}
reentrantlock:
上几次锁,就需要手动释放几次。
public static void main(String[] args) {
ReentrantLock reentrantLock = new ReentrantLock();
new Thread(() -> {
try {
reentrantLock.lock();
System.out.println("第1次获取这个锁,这个锁是:"+reentrantLock);
int index = 1;
while (true) {
try {
reentrantLock.lock();
System.out.println("第"+(++index)+"次获取这个锁,这个锁是:"+reentrantLock);
if (index == 10 ) {
break;
}
} finally {
reentrantLock.unlock();
}
}
} finally {
reentrantLock.unlock();
}
}).start();
}
测试结果:

注意:如果此时少释放一次锁会出现什么情况:
正常情况(加锁和释放锁次数相同):
public static void main(String[] args) {
ReentrantLock reentrantLock = new ReentrantLock();
new Thread(() -> {
try {
reentrantLock.lock();
System.out.println("第1次获取这个锁,这个锁是:"+reentrantLock);
int index = 1;
while (true) {
try {
reentrantLock.lock();
System.out.println("第"+(++index)+"次获取这个锁,这个锁是:"+reentrantLock);
if (index == 10 ) {
break;
}
} finally {
reentrantLock.unlock();
}
}
} finally {
reentrantLock.unlock();
}
}).start();
/**
* 构建第二个线程 看是否可以获取锁
*/
new Thread(new Runnable() {
@Override
public void run() {
try {
reentrantLock.lock();
for (int i = 0; i < 5; i++) {
System.out.println("threadName:" + Thread.currentThread().getName());
try {
Thread.sleep(new Random().nextInt(200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} finally {
reentrantLock.unlock();
}
}
}).start();
}
正常测试结果:

异常情况(少释放一次锁):
public static void main(String[] args) {
ReentrantLock reentrantLock = new ReentrantLock();
new Thread(() -> {
try {
reentrantLock.lock();
System.out.println("第1次获取这个锁,这个锁是:"+reentrantLock);
int index = 1;
while (true) {
try {
reentrantLock.lock();
System.out.println("第"+(++index)+"次获取这个锁,这个锁是:"+reentrantLock);
if (index == 10 ) {
break;
}
} finally {
// reentrantLock.unlock(); //锁少释放一次
}
}
} finally {
reentrantLock.unlock();
}
}).start();
/**
* 构建第二个线程 看是否可以获取锁
*/
new Thread(new Runnable() {
@Override
public void run() {
try {
reentrantLock.lock();
for (int i = 0; i < 5; i++) {
System.out.println("threadName:" + Thread.currentThread().getName());
try {
Thread.sleep(new Random().nextInt(200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} finally {
reentrantLock.unlock();
}
}
}).start();
}
异常结果(第二个线程一直没有获取到锁):


浙公网安备 33010602011771号