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 |
---|---|
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 |
holdsLock(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, wait
protected static final String NO_LONGER_UNINTERRUPTIBLE
public int maybeAdjustNewParkStatus(int status)
MonitorSupport
Unsafe.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 MonitorSupport
public void monitorEnter(Object obj)
MonitorSupport
monitorEnter
in class MonitorSupport
public void monitorExit(Object obj)
MonitorSupport
monitorExit
in class MonitorSupport
public Object prepareRelockObject(Object obj)
prepareRelockObject
in class MonitorSupport
public void doRelockObject(Object obj, Object lockData)
doRelockObject
in class MonitorSupport
public boolean holdsLock(Object obj)
MonitorSupport
Thread.holdsLock(java.lang.Object)
.holdsLock
in class MonitorSupport
protected void doWait(Object obj, long timeoutMillis) throws InterruptedException
doWait
in class MonitorSupport
InterruptedException
public void notify(Object obj, boolean notifyAll)
MonitorSupport
Object.notify()
and Object.notifyAll()
.notify
in class MonitorSupport
protected 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)