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 String |
NO_LONGER_UNINTERRUPTIBLE |
| Constructor and Description |
|---|
MultiThreadedMonitorSupport() |
| Modifier and Type | Method and Description |
|---|---|
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 obj,
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(org.graalvm.nativeimage.IsolateThread isolateThread,
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(). |
Object |
prepareRelockObject(Object obj) |
singleton, waitpublic static final Set<Class<?>> FORCE_MONITOR_SLOT_TYPES
protected static final String NO_LONGER_UNINTERRUPTIBLE
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 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 obj, boolean createIfNotExisting)
protected ReentrantLock getOrCreateMonitorFromObject(Object obj, boolean createIfNotExisting, int monitorOffset)
protected ReentrantLock getOrCreateMonitorFromMap(Object obj, boolean createIfNotExisting)
protected static ReentrantLock newMonitorLock()
protected static ReentrantLock newLockedMonitorForThread(org.graalvm.nativeimage.IsolateThread isolateThread, 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 isMonitorLock(ReentrantLock lock)
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)