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

Comparing jsr166/src/test/tck/ReentrantReadWriteLockTest.java (file contents):
Revision 1.80 by jsr166, Sun May 14 02:03:15 2017 UTC vs.
Revision 1.84 by jsr166, Thu Sep 26 20:48:53 2019 UTC

# Line 11 | Line 11 | import static java.util.concurrent.TimeU
11   import java.util.Arrays;
12   import java.util.Collection;
13   import java.util.HashSet;
14 + import java.util.concurrent.Callable;
15   import java.util.concurrent.CountDownLatch;
16   import java.util.concurrent.atomic.AtomicBoolean;
17   import java.util.concurrent.locks.Condition;
18   import java.util.concurrent.locks.Lock;
19   import java.util.concurrent.locks.ReentrantReadWriteLock;
20  
20 import junit.framework.AssertionFailedError;
21   import junit.framework.Test;
22   import junit.framework.TestSuite;
23  
24 + @SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
25   public class ReentrantReadWriteLockTest extends JSR166TestCase {
26      public static void main(String[] args) {
27          main(suite(), args);
# Line 87 | Line 88 | public class ReentrantReadWriteLockTest
88          long startTime = System.nanoTime();
89          while (!lock.hasQueuedThread(t)) {
90              if (millisElapsedSince(startTime) > LONG_DELAY_MS)
91 <                throw new AssertionFailedError("timed out");
91 >                throw new AssertionError("timed out");
92              Thread.yield();
93          }
94          assertTrue(t.isAlive());
# Line 1680 | Line 1681 | public class ReentrantReadWriteLockTest
1681          assertTrue(lock.writeLock().toString().contains("Unlocked"));
1682      }
1683  
1684 +    /**
1685 +     * ThreadMXBean reports the blockers that we expect.
1686 +     */
1687 +    public void testBlockers() {
1688 +        if (!testImplementationDetails) return;
1689 +        final boolean fair = randomBoolean();
1690 +        final boolean timedAcquire = randomBoolean();
1691 +        final boolean timedAwait = randomBoolean();
1692 +        final String syncClassName = fair
1693 +            ? "ReentrantReadWriteLock$FairSync"
1694 +            : "ReentrantReadWriteLock$NonfairSync";
1695 +        final String conditionClassName
1696 +            = "AbstractQueuedSynchronizer$ConditionObject";
1697 +        final Thread.State expectedAcquireState = timedAcquire
1698 +            ? Thread.State.TIMED_WAITING
1699 +            : Thread.State.WAITING;
1700 +        final Thread.State expectedAwaitState = timedAwait
1701 +            ? Thread.State.TIMED_WAITING
1702 +            : Thread.State.WAITING;
1703 +        final Lock lock = new ReentrantReadWriteLock(fair).writeLock();
1704 +        final Condition condition = lock.newCondition();
1705 +        final AtomicBoolean conditionSatisfied = new AtomicBoolean(false);
1706 +        lock.lock();
1707 +        final Thread thread = newStartedThread((Action) () -> {
1708 +            if (timedAcquire)
1709 +                lock.tryLock(LONGER_DELAY_MS, MILLISECONDS);
1710 +            else
1711 +                lock.lock();
1712 +            while (!conditionSatisfied.get())
1713 +                if (timedAwait)
1714 +                    condition.await(LONGER_DELAY_MS, MILLISECONDS);
1715 +                else
1716 +                    condition.await();
1717 +        });
1718 +        Callable<Boolean> waitingForLock = () -> {
1719 +            String className;
1720 +            return thread.getState() == expectedAcquireState
1721 +            && (className = blockerClassName(thread)) != null
1722 +            && className.endsWith(syncClassName);
1723 +        };
1724 +        waitForThreadToEnterWaitState(thread, waitingForLock);
1725 +
1726 +        lock.unlock();
1727 +        Callable<Boolean> waitingForCondition = () -> {
1728 +            String className;
1729 +            return thread.getState() == expectedAwaitState
1730 +            && (className = blockerClassName(thread)) != null
1731 +            && className.endsWith(conditionClassName);
1732 +        };
1733 +        waitForThreadToEnterWaitState(thread, waitingForCondition);
1734 +
1735 +        // politely release the waiter
1736 +        conditionSatisfied.set(true);
1737 +        lock.lock();
1738 +        try {
1739 +            condition.signal();
1740 +        } finally { lock.unlock(); }
1741 +
1742 +        awaitTermination(thread);
1743 +    }
1744   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines