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.79 by jsr166, Sun Jan 1 20:34:39 2017 UTC vs.
Revision 1.83 by jsr166, Sun Sep 22 01:59:57 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 1009 | Line 1010 | public class ReentrantReadWriteLockTest
1010      public void testAwaitUninterruptibly()      { testAwaitUninterruptibly(false); }
1011      public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
1012      public void testAwaitUninterruptibly(boolean fair) {
1013 <        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1014 <        final Condition c = lock.writeLock().newCondition();
1013 >        final Lock lock = new ReentrantReadWriteLock(fair).writeLock();
1014 >        final Condition condition = lock.newCondition();
1015          final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
1016  
1017          Thread t1 = newStartedThread(new CheckedRunnable() {
1018              public void realRun() {
1019                  // Interrupt before awaitUninterruptibly
1020 <                lock.writeLock().lock();
1020 >                lock.lock();
1021                  pleaseInterrupt.countDown();
1022                  Thread.currentThread().interrupt();
1023 <                c.awaitUninterruptibly();
1023 >                condition.awaitUninterruptibly();
1024                  assertTrue(Thread.interrupted());
1025 <                lock.writeLock().unlock();
1025 >                lock.unlock();
1026              }});
1027  
1028          Thread t2 = newStartedThread(new CheckedRunnable() {
1029              public void realRun() {
1030                  // Interrupt during awaitUninterruptibly
1031 <                lock.writeLock().lock();
1031 >                lock.lock();
1032                  pleaseInterrupt.countDown();
1033 <                c.awaitUninterruptibly();
1033 >                condition.awaitUninterruptibly();
1034                  assertTrue(Thread.interrupted());
1035 <                lock.writeLock().unlock();
1035 >                lock.unlock();
1036              }});
1037  
1038          await(pleaseInterrupt);
1038        lock.writeLock().lock();
1039        lock.writeLock().unlock();
1039          t2.interrupt();
1040 <
1041 <        assertThreadStaysAlive(t1);
1042 <        assertTrue(t2.isAlive());
1043 <
1044 <        lock.writeLock().lock();
1045 <        c.signalAll();
1046 <        lock.writeLock().unlock();
1040 >        lock.lock();
1041 >        lock.unlock();
1042 >        assertThreadBlocks(t1, Thread.State.WAITING);
1043 >        assertThreadBlocks(t2, Thread.State.WAITING);
1044 >
1045 >        lock.lock();
1046 >        condition.signalAll();
1047 >        lock.unlock();
1048  
1049          awaitTermination(t1);
1050          awaitTermination(t2);
# Line 1681 | 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