-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Closed
Labels
improvementAn improvement / new feature ideaAn improvement / new feature idea
Milestone
Description
Sample to reproduce:
InputStream in = load();
Jsoup.parse(in, "UTF-8", "http://example.org/")
Running that with -Djdk.tracePinnedThreads=full
in Java-21(on a virtual thread) will give the following print:
Thread[#35,ForkJoinPool-1-worker-4,5,CarrierThreads]
…
java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:405) <== monitors:1
org.jsoup.internal.ConstrainableInputStream.read(ConstrainableInputStream.java:64)
…
BufferedInputStream
was refactored to be virtual thread friendly, however with a caveat: It becomes unfriendly when inherited (which ConstrainableInputStream
does):
public BufferedInputStream(InputStream in, int size) {
…
if (getClass() == BufferedInputStream.class) { // false in case of ConstrainableInputStream
lock = InternalLock.newLockOrNull();
…
} else {
lock = null;
…
}
}
…
public int read(byte[] b, int off, int len) throws IOException {
if (lock != null) {
… // Virtual Thread friendly code
} else {
synchronized (this) {
return implRead(b, off, len); // Line 405
}
}
}
With Loom gaining popularity with the latest LTS release, do you want to reconsider ConstrainableInputStream
inheriting from BufferedInputStream
? A possible mitigation might be to use composition instead, i.e. inherit from FilterInputStream
and use a new instance of BufferedInputStream
as source:
class ConstrainableInputStream extends FilterInputStream {
…
static ConstrainableInputStream wrap(InputStream in,…) {
var buffered = new BufferedInputStream(in);
return new ConstrainableInputStream(buffered);
}
}
Metadata
Metadata
Assignees
Labels
improvementAn improvement / new feature ideaAn improvement / new feature idea