On 13 Mar 2025, at 4:20, Per Minborg wrote: > … >> Reentrancy into here seems really buggy, I would endorse disallowing it >> >> instead. In that case, a `ReentrantLock` seems better than the native >> monitor as we can cheaply check `lock.isHeldByCurrentThread()` > > StableValueImpl was carefully designed to minimize memory footprint. Adding a > lock would inflate memory usage substantially.
+1 from me A similar level of concern with footprint was in my mind in my earlier comment, where I claimed that capturing /this/ in a lambda is suboptimal. The inefficiency is in object creation and footprint, since an extra copy of /this/ must be tracked. > >> src/java.base/share/classes/jdk/internal/lang/stable/StableValueImpl.java >> line 159: >> >>> 157: private boolean wrapAndCas(Object value) { >>> 158: // This upholds the invariant, a `@Stable` field is written to >>> at most once >>> 159: return UNSAFE.compareAndSetReference(this, >>> UNDERLYING_DATA_OFFSET, null, wrap(value)); >> >> There is no need for a cas here as all setters have to hold the lock. We >> should have a dedicated private `set` that asserts `Thread.holdsLock(this)`. > > This is more of a belt and suspenders solution. It is true that it is > redundant. A set volatile would suffice here. There is a broad choice at the beginning of this design whether to use a mutex (as <clinit> and ClassValue do) or use lock-free CAS (as condy/indy do). This API, which is more parallel to the higher-level <clinit> and ClassValue, uses a mutex. The choice connects to the rules about handling races. Surely, two threads can ask concurrently for a SV state, and both may “suggest” a lambda to give it a value. Now we come to a fork in the road: Do we select at most one lambda to run? Or, do we let both lambdas run and then pick a winner? The first requires a mutex. The second is lock-free and uses CAS. It’s a binary choice. I don’t think we ever need the belt and suspenders. I agree that StableValue is like ClassValue and not like condy, so it should not be playing with lock free stuff. (Or did I forget something??) — John