public class MultiThreadedMonitorSupport extends MonitorSupport
Most objects used in synchronization operations have a dedicated memory in the object to store a
ReentrantLock. The static analysis finds out which classes are used for synchronization
(and thus need a monitor) and assigns a monitor offset to point to the slot for the monitor. The monitor is implemented with a ReentrantLock.
There are a few exceptions: String and DynamicHub objects never have monitor
fields because we want instances in the image heap to be immutable. Arrays never have monitor
fields because it would increase the size of every array and it is not possible to distinguish
between arrays with different header sizes. See
UniverseBuilder.canHaveMonitorFields(AnalysisType) for details.
Synchronization on String, arrays, and other types not detected by the static analysis
(like synchronization via JNI) fall back to a monitor stored in MultiThreadedMonitorSupport.additionalMonitors.
Condition objects are used to implement Object.wait() and Object.notify(). When an
object monitor needs a condition object, it is atomically swapped into its
Target_java_util_concurrent_locks_ReentrantLock_NonfairSync.objectMonitorCondition field.
| Modifier and Type | Field and Description |
|---|---|
static Set<Class<?>> |
FORCE_MONITOR_SLOT_TYPES
Types that are used to implement the secondary storage for monitor slots cannot themselves
use the additionalMonitors map.
|
protected static FastThreadLocalInt |
lockedMonitors
This is only used for preempting a continuation in the experimental Loom JDK support.
|
protected static String |
NO_LONGER_UNINTERRUPTIBLE |
| Constructor and Description |
|---|
MultiThreadedMonitorSupport() |
| Modifier and Type | Method and Description |
|---|---|
int |
countThreadLock(org.graalvm.nativeimage.IsolateThread vmThread) |
void |
doRelockObject(Object obj,
Object lockData) |
protected void |
doWait(Object obj,
long timeoutMillis) |
protected ReentrantLock |
ensureLocked(Object obj)
Returns the lock of the object.
|
ReentrantLock |
getMonitorForTesting(Object obj) |
protected static int |
getMonitorOffset(Object obj) |
protected AbstractQueuedSynchronizer.ConditionObject |
getOrCreateCondition(ReentrantLock monitorLock,
boolean createIfNotExisting) |
protected ReentrantLock |
getOrCreateMonitor(Object unreplacedObject,
boolean createIfNotExisting) |
protected ReentrantLock |
getOrCreateMonitorFromMap(Object obj,
boolean createIfNotExisting) |
protected ReentrantLock |
getOrCreateMonitorFromObject(Object obj,
boolean createIfNotExisting,
int monitorOffset) |
boolean |
isLockedByAnyThread(Object obj)
Determines whether the object's monitor is locked by the current or any other thread.
|
boolean |
isLockedByCurrentThread(Object obj)
Implements the semantics of
Thread.holdsLock(java.lang.Object). |
protected static boolean |
isMonitorCondition(Object obj) |
protected static boolean |
isMonitorLock(ReentrantLock lock) |
protected static boolean |
isMonitorLockSynchronizer(Object obj) |
int |
maybeAdjustNewParkStatus(int status)
Called from
Unsafe.park when changing the current thread's state before parking the
thread. |
void |
monitorEnter(Object obj)
Implements the semantics of the monitorenter bytecode.
|
void |
monitorExit(Object obj)
Implements the semantics of the monitorexit bytecode.
|
protected static ReentrantLock |
newLockedMonitorForThread(Thread thread,
int recursionDepth)
Creates a new
ReentrantLock that is locked by the provided thread. |
protected static ReentrantLock |
newMonitorLock() |
void |
notify(Object obj,
boolean notifyAll)
Implements the semantics of
Object.notify() and Object.notifyAll(). |
protected static void |
onMonitorLocked() |
protected static void |
onMonitorUnlocked() |
Object |
prepareRelockObject(Object obj) |
singleton, waitprotected static final FastThreadLocalInt lockedMonitors
public static final Set<Class<?>> FORCE_MONITOR_SLOT_TYPES
protected static final String NO_LONGER_UNINTERRUPTIBLE
protected static void onMonitorLocked()
protected static void onMonitorUnlocked()
public int maybeAdjustNewParkStatus(int status)
MonitorSupportUnsafe.park when changing the current thread's state before parking the
thread. When the thread is parked due to a monitor operation, we need to alter the new thread
state so Thread.getState() gives the expected result.maybeAdjustNewParkStatus in class MonitorSupportpublic void monitorEnter(Object obj)
MonitorSupportmonitorEnter in class MonitorSupportpublic void monitorExit(Object obj)
MonitorSupportmonitorExit in class MonitorSupportpublic Object prepareRelockObject(Object obj)
prepareRelockObject in class MonitorSupportpublic void doRelockObject(Object obj, Object lockData)
doRelockObject in class MonitorSupportpublic boolean isLockedByCurrentThread(Object obj)
MonitorSupportThread.holdsLock(java.lang.Object).isLockedByCurrentThread in class MonitorSupportpublic boolean isLockedByAnyThread(Object obj)
MonitorSupportisLockedByAnyThread in class MonitorSupportpublic int countThreadLock(org.graalvm.nativeimage.IsolateThread vmThread)
countThreadLock in class MonitorSupportprotected void doWait(Object obj, long timeoutMillis) throws InterruptedException
doWait in class MonitorSupportInterruptedExceptionpublic void notify(Object obj, boolean notifyAll)
MonitorSupportObject.notify() and Object.notifyAll().notify in class MonitorSupportprotected ReentrantLock ensureLocked(Object obj)
protected static int getMonitorOffset(Object obj)
protected final ReentrantLock getOrCreateMonitor(Object unreplacedObject, boolean createIfNotExisting)
protected ReentrantLock getOrCreateMonitorFromObject(Object obj, boolean createIfNotExisting, int monitorOffset)
protected ReentrantLock getOrCreateMonitorFromMap(Object obj, boolean createIfNotExisting)
protected static ReentrantLock newMonitorLock()
protected static boolean isMonitorLock(ReentrantLock lock)
protected static ReentrantLock newLockedMonitorForThread(Thread thread, int recursionDepth)
ReentrantLock that is locked by the provided thread. This requires
patching of internal state, since there is no public API in ReentrantLock to do that
(for a good reason, because it is a highly unusual operation).protected static boolean isMonitorLockSynchronizer(Object obj)
public ReentrantLock getMonitorForTesting(Object obj)
protected AbstractQueuedSynchronizer.ConditionObject getOrCreateCondition(ReentrantLock monitorLock, boolean createIfNotExisting)
protected static boolean isMonitorCondition(Object obj)