单个线程也能造成死锁

APUE:如果线程试图对一个mutex加锁两次,那么它就会陷入死锁。

分析一下:

1. 第一次上锁成功后,获得锁

2. 第二次上锁时需要等待锁被本线程释放;而本线程目前已经在等待锁,无法释放第一次获得的锁;所以这个等待将是无限期的。

可重入锁(reentrant lock)就是用来避免这种情况发生的: 第二次上锁时不需要等待第一次上的锁被释放;java的ReentrantLock和synchronized关键字都使用了这种机制。

不过,Java里ReentractReadWriteLock在JDK 1.6 update 18 之前仍然可能造成单线程死锁:

  • 拿到一个读锁,然后要求拿写锁。拿写锁时需要等待读锁被本线程释放(这里要拿的锁而已经锁上的锁是不同的,所以Reentrant不起作用),而本线程已经在等待写锁。无限循环的等待,造成死锁。这就是所谓的“读锁不可升级”

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.