ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantLockTest.java
(Generate patch)

Comparing jsr166/src/test/tck/ReentrantLockTest.java (file contents):
Revision 1.69 by jsr166, Sun Jul 22 22:13:55 2018 UTC vs.
Revision 1.70 by jsr166, Sun Sep 22 01:59:57 2019 UTC

# Line 12 | Line 12 | import java.util.ArrayList;
12   import java.util.Arrays;
13   import java.util.Collection;
14   import java.util.HashSet;
15 + import java.util.concurrent.Callable;
16   import java.util.concurrent.CountDownLatch;
17   import java.util.concurrent.CyclicBarrier;
18   import java.util.concurrent.ThreadLocalRandom;
19 + import java.util.concurrent.atomic.AtomicBoolean;
20   import java.util.concurrent.locks.Condition;
21 + import java.util.concurrent.locks.Lock;
22   import java.util.concurrent.locks.ReentrantLock;
23  
24   import junit.framework.Test;
# Line 1195 | Line 1198 | public class ReentrantLockTest extends J
1198              assertFalse(thread.isAlive());
1199          }
1200      }
1201 +
1202 +    /**
1203 +     * ThreadMXBean reports the blockers that we expect.
1204 +     */
1205 +    public void testBlockers() {
1206 +        if (!testImplementationDetails) return;
1207 +        final boolean fair = randomBoolean();
1208 +        final boolean timedAcquire = randomBoolean();
1209 +        final boolean timedAwait = randomBoolean();
1210 +        final String syncClassName = fair
1211 +            ? "ReentrantLock$FairSync"
1212 +            : "ReentrantLock$NonfairSync";
1213 +        final String conditionClassName
1214 +            = "AbstractQueuedSynchronizer$ConditionObject";
1215 +        final Thread.State expectedAcquireState = timedAcquire
1216 +            ? Thread.State.TIMED_WAITING
1217 +            : Thread.State.WAITING;
1218 +        final Thread.State expectedAwaitState = timedAwait
1219 +            ? Thread.State.TIMED_WAITING
1220 +            : Thread.State.WAITING;
1221 +        final Lock lock = new ReentrantLock(fair);
1222 +        final Condition condition = lock.newCondition();
1223 +        final AtomicBoolean conditionSatisfied = new AtomicBoolean(false);
1224 +        lock.lock();
1225 +        final Thread thread = newStartedThread((Action) () -> {
1226 +            if (timedAcquire)
1227 +                lock.tryLock(LONGER_DELAY_MS, MILLISECONDS);
1228 +            else
1229 +                lock.lock();
1230 +            while (!conditionSatisfied.get())
1231 +                if (timedAwait)
1232 +                    condition.await(LONGER_DELAY_MS, MILLISECONDS);
1233 +                else
1234 +                    condition.await();
1235 +        });
1236 +        Callable<Boolean> waitingForLock = () -> {
1237 +            String className;
1238 +            return thread.getState() == expectedAcquireState
1239 +            && (className = blockerClassName(thread)) != null
1240 +            && className.endsWith(syncClassName);
1241 +        };
1242 +        waitForThreadToEnterWaitState(thread, waitingForLock);
1243 +
1244 +        lock.unlock();
1245 +        Callable<Boolean> waitingForCondition = () -> {
1246 +            String className;
1247 +            return thread.getState() == expectedAwaitState
1248 +            && (className = blockerClassName(thread)) != null
1249 +            && className.endsWith(conditionClassName);
1250 +        };
1251 +        waitForThreadToEnterWaitState(thread, waitingForCondition);
1252 +
1253 +        // politely release the waiter
1254 +        conditionSatisfied.set(true);
1255 +        lock.lock();
1256 +        try {
1257 +            condition.signal();
1258 +        } finally { lock.unlock(); }
1259 +
1260 +        awaitTermination(thread);
1261 +    }
1262   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines