From d02e76cd307b3445eca182ea51ad6a7e606cf044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=97=E6=B5=94?= <1472459179@qq.com> Date: Wed, 5 Aug 2026 11:00:58 +0800 Subject: [PATCH] =?UTF-8?q?=E9=94=81-StampedLock=E7=9F=A5=E8=AF=86?= =?UTF-8?q?=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原句比较笼统 --- docs/java/concurrent/java-concurrent-questions-02.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/java/concurrent/java-concurrent-questions-02.md b/docs/java/concurrent/java-concurrent-questions-02.md index 501386a8083..6301e7ca59b 100644 --- a/docs/java/concurrent/java-concurrent-questions-02.md +++ b/docs/java/concurrent/java-concurrent-questions-02.md @@ -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 // 写锁