jsedding commented on code in PR #3069:
URL: https://github.com/apache/jackrabbit-oak/pull/3069#discussion_r3794304044
##########
oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/SyncConfigTrackerConcurrencyTest.java:
##########
@@ -123,51 +138,56 @@ public void concurrentGetServiceReferencesBlocksReaders()
throws Exception {
*/
@Test
public void concurrentIsEnabledDoesNotBlockReaders() throws Exception {
- boolean blockedOnTracked =
sampleForBlockingOnTrackedMonitor(tracker::isEnabled);
- assertFalse("expected isEnabled() to no longer contend on the
ServiceTracker$Tracked monitor "
- + "once service references are cached (OAK-12341)",
blockedOnTracked);
+ long blockedMs = sampleForBlockingOnTrackedMonitor(tracker::isEnabled);
+ LOG.info("Contended threads were blocked for {}ms", blockedMs);
+ assertEquals("expected isEnabled() to no longer contend on the
ServiceTracker$Tracked monitor "
+ + "once service references are cached (OAK-12341)", 0,
blockedMs);
}
/**
- * Runs {@code action} on {@link #THREAD_COUNT} threads in a tight loop for
- * {@link #SAMPLE_MILLIS} and polls {@link ThreadMXBean} throughout,
returning {@code true} as
- * soon as any thread is observed {@code BLOCKED} while waiting to lock a
- * {@code ServiceTracker$Tracked} instance held by another thread.
+ * Runs {@code action} directly on {@link #THREAD_COUNT} threads in a
tight loop, so all of
+ * them contend on the tracker concurrently from the start rather than
serializing through a
+ * single task submitter, and polls the {@link ThreadMXBean} of all worker
threads in a batch
+ * for {@link #SAMPLE_MILLIS}, returning the accumulated blocked time
observed on a
+ * {@code ServiceTracker$Tracked} monitor.
*/
- @SuppressWarnings("deprecation") // Thread.threadId() replacement requires
Java 19+; this module targets 17
- private boolean sampleForBlockingOnTrackedMonitor(Runnable action) throws
Exception {
+ private long sampleForBlockingOnTrackedMonitor(Runnable action) throws
Exception {
+ ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+ assumeTrue("JVM supporting thread contention monitoring required",
+ threadMXBean.isThreadContentionMonitoringSupported());
+ threadMXBean.setThreadContentionMonitoringEnabled(true);
+
ExecutorService pool = Executors.newFixedThreadPool(THREAD_COUNT);
- CountDownLatch started = new CountDownLatch(THREAD_COUNT);
+ CountDownLatch allThreadsStarted = new CountDownLatch(THREAD_COUNT);
AtomicBoolean stop = new AtomicBoolean(false);
- List<Long> threadIds = new CopyOnWriteArrayList<>();
+ long[] threadIds = new long[THREAD_COUNT];
Review Comment:
While it is safe to _write_ to the array from multiple threads, as long as
each thread only writes to a given array index (what you are doing here), there
is no guarantee that these updates are visible to other threads. I.e. the call
to `threadMXBean.getThreadInfo(threadIds)` _may_ not see the thread ID written
into the array (and would presumably see `null`).
See https://stackoverflow.com/a/8978397
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]