Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/java/concurrent/java-concurrent-questions-02.md
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,11 @@ long tryConvertToReadLock(long stamp){}
long tryConvertToOptimisticRead(long stamp){}
```

`StampedLock` 在获取锁的时候会返回一个 long 型的数据戳,该数据戳用于稍后的锁释放参数,如果返回的数据戳为 0 则表示锁获取失败。当前线程持有了锁再次获取锁还是会返回一个新的数据戳,这也是 `StampedLock` 不可重入的原因。
`StampedLock` 在获取锁的时候会返回一个 long 型的数据戳,该数据戳用于稍后的锁释放参数,如果返回的数据戳为 0 则表示锁获取失败。当前线程持有了锁再次获取锁时返回情况要看当前持有什么锁、再次申请什么锁,以及使用的是阻塞方法还是`try`方法:
- **当前线程持有写锁,再次获取写锁**:由于写锁是独占锁,第二次获取必须等待,但第一个写锁又要等待第二次调用返回后才能释放,于是当前线程把自己锁住了。结果就是一直阻塞,无法返回。
- **使用`tryWriteLock()`时,会返回0**:tryWriteLock()不会一直等待,它会立即尝试。当获取成功,则返回非0的stamp;获取失败,则返回0。
- **同一线程再次获取悲观读锁,会返回新的数据戳**:读锁是共享锁,读锁与读锁之间不冲突,所以正常返回数据戳。
真正的“可重入锁”会识别线程身份,虽然StampedLock这里同一个线程可以获取2次读锁,返回2个stamp,但StampedLock不记录锁的线程所有权。判断是否可重入,重点看独占写锁。StampedLock的写锁无法由同一个线程再次获取,所以它是不可重入的。

```java
// 写锁
Expand Down