Created https://bugs.openjdk.org/browse/JDK-8390781.
You are right on synchronizedCollection -- this one is good as is. As
for java.nio.channels.SelectableChannel, I'm not sure I understand. It
is defined as follows:
/**
* Retrieves the object upon which the {@link #configureBlocking
* configureBlocking} and {@link #register register} methods synchronize.
* This is often useful in the implementation of adaptors that require a
* specific blocking mode to be maintained for a short period of time.
*
* @return The blocking-mode lock object
*/
public abstract Object blockingLock();
So an implementor might mistakenly return a value object, no?
value class X { }
private final Object valueObj = new X();
@Override
public Object blockingLock() {
return valueObj;
}
On Thu, Aug 20, 2026 at 4:40 PM Alan Bateman <[email protected]> wrote:
>
> On 20/08/2026 15:38, Pavel Rappo wrote:
> > I have a quick question on the library side of JEP 401.
> >
> > In JDK, there are cases where an implementor or client provides an
> > object to be used as a monitor. I can think of these, but there are
> > likely more:
> >
> > * java.util.Collections#synchronizedCollection(java.util.Collection<T>)
> > * java.io.Reader#lock and java.io.Writer#lock
> > * java.nio.channels.SelectableChannel#blockingLock
> >
> > If a value object is provided, any synchronization attempt will fail.
> > That said, I wonder if there are any plans to be more helpful here so
> > that any failures are warned about or happen sooner.
>
> This is good topic as there are a number of APIs that might need
> clarification.
>
> For synchronizedCollection, it synchronizes on the wrapper so I don't
> think there is an issue there.
>
> The Reader/Writer constructors that take a lock object are protected
> methods. They could potentially reject a value object but then we see
> that the "lock" field is a non-final protected field that the subclass
> can change at any time. Guidance in the API docs might avoid bug reports
> from people pointing this out.
>
> SelectableChannel::blockingLock returns the lock object, you can't set
> it to a value object. (Separately, we should deprecate this method at
> some point as it can't be used with channels that support concurrent I/O
> operations. It was originally intended for socket adaptors. The JDK
> implementation does not use it, except to coordinate changing the
> blocking mode.)
>
> Another example that comes to mind is ClassLoader::getClassLoadingLock
> where it wouldn't make sense for a custom class loader to override the
> method and return a value object. TimeUnit.timedWait is an example where
> calling it with a value object will throw IMSE as the caller could not
> have synchronized on the monitor, so I think that one is okay.
>
> Can you create an issue in JBS as I think it would be useful to identity
> classes where some clarification is required, and maybe where
> IdentityException needs to be specified to be thrown.
>
> -Alan