Add multithreading module: odd-even, ping-pong, ordered threads, deadlock detection and fixes, virtual-thread variants (25 tests)

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017ic4b7rnC7jppGGdHGESvy
This commit is contained in:
Claude
2026-10-28 18:10:23 +00:00
parent f80e1079a8
commit 94306c50ab
29 changed files with 1021 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
OddEvenWaitNotify (platform threads), max=10
[odd:1, even:2, odd:3, even:4, odd:5, even:6, odd:7, even:8, odd:9, even:10]
OddEvenSemaphore (platform threads), max=10
[odd:1, even:2, odd:3, even:4, odd:5, even:6, odd:7, even:8, odd:9, even:10]
OddEvenLockCondition (platform threads), max=10
[odd:1, even:2, odd:3, even:4, odd:5, even:6, odd:7, even:8, odd:9, even:10]
+2
View File
@@ -0,0 +1,2 @@
PingPong, 4 rounds
[ping, pong, ping, pong, ping, pong, ping, pong]
@@ -0,0 +1,5 @@
Started T3, T2, T1 (in that order). Execution order:
latches: [T1, T2, T3]
join chain: [T1, T2, T3]
Round robin, 3 threads, max=10:
[worker-1:1, worker-2:2, worker-3:3, worker-1:4, worker-2:5, worker-3:6, worker-1:7, worker-2:8, worker-3:9, worker-1:10]
+14
View File
@@ -0,0 +1,14 @@
== NAIVE ==
findDeadlockedThreads: DEADLOCK
transfer-A-to-B is WAITING on java.util.concurrent.locks.ReentrantLock$NonfairSync owned by transfer-B-to-A
transfer-B-to-A is WAITING on java.util.concurrent.locks.ReentrantLock$NonfairSync owned by transfer-A-to-B
after interrupting both threads: total balance = 2000
== ORDERED ==
both transfers completed, no deadlock to detect
balances A=930 B=1070
== TRY_LOCK ==
both transfers completed, no deadlock to detect
balances A=930 B=1070 retries>0=true
== NAIVE on virtual threads ==
thread states: [WAITING, WAITING]
findDeadlockedThreads: none (virtual threads are invisible to it)
@@ -0,0 +1,6 @@
carrier parallelism = 1
OddEvenWaitNotify on virtual threads, max=10
[odd:1, even:2, odd:3, even:4, odd:5, even:6, odd:7, even:8, odd:9, even:10]
Round robin: 1000 virtual threads, max=3000 -> 3000 events
first 3: [worker-1:1, worker-2:2, worker-3:3]
last 3: [worker-998:2998, worker-999:2999, worker-1000:3000]
+26
View File
@@ -0,0 +1,26 @@
PASS DeadlockTest.naiveLockingDeadlocksAndTheJvmSaysSo
PASS DeadlockTest.consistentLockOrderingRemovesTheCycle
PASS DeadlockTest.fixesAlsoWorkOnVirtualThreads
PASS DeadlockTest.tryLockWithBackOffTurnsDeadlockIntoCountedRetries
PASS DeadlockTest.deadlockedVirtualThreadsAreInvisibleToFindDeadlockedThreads
PASS OddEvenTest.everyImplementationPrintsExactlyOneToTwentyInOrder(ThreadKind)[1]
PASS OddEvenTest.everyImplementationPrintsExactlyOneToTwentyInOrder(ThreadKind)[2]
PASS OddEvenTest.twoDifferentThreadsDoTheWork(ThreadKind)[1]
PASS OddEvenTest.twoDifferentThreadsDoTheWork(ThreadKind)[2]
PASS OddEvenTest.stableAcrossManyRunsAndOddMax(ThreadKind)[1]
PASS OddEvenTest.stableAcrossManyRunsAndOddMax(ThreadKind)[2]
PASS OddEvenTest.zeroAndOneAreHandled(ThreadKind)[1]
PASS OddEvenTest.zeroAndOneAreHandled(ThreadKind)[2]
PASS OrderedThreadsTest.roundRobinOfThreeThreadsPrintsOneToTen(ThreadKind)[1]
PASS OrderedThreadsTest.roundRobinOfThreeThreadsPrintsOneToTen(ThreadKind)[2]
PASS OrderedThreadsTest.latchesRunT1T2T3EvenThoughT3StartsFirst(ThreadKind)[1]
PASS OrderedThreadsTest.latchesRunT1T2T3EvenThoughT3StartsFirst(ThreadKind)[2]
PASS OrderedThreadsTest.thousandVirtualThreadsStillPrintInOrder
PASS OrderedThreadsTest.joinChainRunsT1T2T3(ThreadKind)[1]
PASS OrderedThreadsTest.joinChainRunsT1T2T3(ThreadKind)[2]
PASS PingPongTest.zeroRoundsPrintNothing(ThreadKind)[1]
PASS PingPongTest.zeroRoundsPrintNothing(ThreadKind)[2]
PASS PingPongTest.alternatesStrictlyForGivenRounds(ThreadKind)[1]
PASS PingPongTest.alternatesStrictlyForGivenRounds(ThreadKind)[2]
PASS SingleCarrierVirtualThreadTest.waitNotifyFinishesOnOneCarrierThread
25 tests, 0 failures