Skip to content

[JDK 21] Make synchronized code Loom-friendly #17045

@wendigo

Description

@wendigo

Background

According to https://openjdk.org/jeps/425:

There are two scenarios in which a virtual thread cannot be unmounted during blocking operations because it is pinned to its carrier:

  • When it executes code inside a synchronized block or method, or
  • When it executes a native method or a foreign function.

Pinning does not make an application incorrect, but it might hinder its scalability. If a virtual thread performs a blocking operation such as I/O or BlockingQueue.take() while it is pinned, then its carrier and the underlying OS thread are blocked for the duration of the operation. Frequent pinning for long durations can harm the scalability of an application by capturing carriers.

The scheduler does not compensate for pinning by expanding its parallelism. Instead, avoid frequent and long-lived pinning by revising synchronized blocks or methods that run frequently and guard potentially long I/O operations to use java.util.concurrent.locks.ReentrantLock instead. There is no need to replace synchronized blocks and methods that are used infrequently (e.g., only performed at startup) or that guard in-memory operations. As always, strive to keep locking policies simple and clear.

Other references (solutions & problems)

Discussion

I personally opt-in for the ReentrantLock usage pattern introduced by the pgjdbc team:

public final class ResourceLock 
		extends ReentrantLock 
		implements AutoCloseable
{
    @MustBeClosed
	public ResourceLock obtain() 
  	{
		lock();
	    return this;
  	}

  	@Override
  	public void close() 
	{
    	this.unlock();
  	}
}

This is then used in try-with-resource blocks like this:

	try (ResourceLock ignored = lock.obtain()) {
    		// critical section
    }

This plays nicely with existing tools/checks that we have (https://errorprone.info/bugpattern/MustBeClosedChecker)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions