< prev index next >

test/jdk/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java

Print this page
8225490: Miscellaneous changes imported from jsr166 CVS 2019-09
Reviewed-by: martin, alanb


  22 
  23 /*
  24  * This file is available under and governed by the GNU General Public
  25  * License version 2 only, as published by the Free Software Foundation.
  26  * However, the following notice accompanied the original version of this
  27  * file:
  28  *
  29  * Written by Doug Lea with assistance from members of JCP JSR-166
  30  * Expert Group and released to the public domain, as explained at
  31  * http://creativecommons.org/publicdomain/zero/1.0/
  32  * Other contributors include Andrew Wright, Jeffrey Hayes,
  33  * Pat Fisher, Mike Judd.
  34  */
  35 
  36 import static java.util.concurrent.TimeUnit.MILLISECONDS;
  37 import static java.util.concurrent.TimeUnit.NANOSECONDS;
  38 
  39 import java.util.Arrays;
  40 import java.util.Collection;
  41 import java.util.HashSet;
  42 import java.util.concurrent.ThreadLocalRandom;
  43 import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
  44 import java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject;
  45 
  46 import junit.framework.Test;
  47 import junit.framework.TestSuite;
  48 
  49 @SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
  50 public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase {
  51     public static void main(String[] args) {
  52         main(suite(), args);
  53     }
  54     public static Test suite() {
  55         return new TestSuite(AbstractQueuedLongSynchronizerTest.class);
  56     }
  57 
  58     /**
  59      * A simple mutex class, adapted from the class javadoc.  Exclusive
  60      * acquire tests exercise this as a sample user extension.
  61      *
  62      * Unlike the javadoc sample, we don't track owner thread via


1269         assertTrue(c.awaitNanos(0L) <= 0);
1270         assertFalse(c.await(0L, NANOSECONDS));
1271         sync.release();
1272     }
1273 
1274     /**
1275      * awaitNanos/timed await with maximum negative wait times does not underflow
1276      */
1277     public void testAwait_NegativeInfinity() throws InterruptedException {
1278         final Mutex sync = new Mutex();
1279         final ConditionObject c = sync.newCondition();
1280         sync.acquire();
1281         assertTrue(c.awaitNanos(Long.MIN_VALUE) <= 0);
1282         assertFalse(c.await(Long.MIN_VALUE, NANOSECONDS));
1283         sync.release();
1284     }
1285 
1286     /**
1287      * Tests scenario for
1288      * JDK-8191937: Lost interrupt in AbstractQueuedSynchronizer when tryAcquire methods throw

1289      */
1290     public void testInterruptedFailingAcquire() throws InterruptedException {
1291         final RuntimeException ex = new RuntimeException();


1292 
1293         // A synchronizer only offering a choice of failure modes
1294         class Sync extends AbstractQueuedLongSynchronizer {
1295             boolean pleaseThrow;









1296             @Override protected boolean tryAcquire(long ignored) {
1297                 if (pleaseThrow) throw ex;
1298                 return false;
1299             }
1300             @Override protected long tryAcquireShared(long ignored) {
1301                 if (pleaseThrow) throw ex;
1302                 return -1;
1303             }
1304             @Override protected boolean tryRelease(long ignored) {
1305                 return true;
1306             }
1307             @Override protected boolean tryReleaseShared(long ignored) {
1308                 return true;
1309             }
1310         }
1311 
1312         final Sync s = new Sync();
1313 































1314         final Thread thread = newStartedThread(new CheckedRunnable() {
1315             public void realRun() {
1316                 try {
1317                     if (ThreadLocalRandom.current().nextBoolean())
1318                         s.acquire(1);
1319                     else
1320                         s.acquireShared(1);
1321                     shouldThrow();
1322                 } catch (Throwable t) {
1323                     assertSame(ex, t);
1324                     assertTrue(Thread.interrupted());


1325                 }
1326             }});

1327         waitForThreadToEnterWaitState(thread);
1328         assertSame(thread, s.getFirstQueuedThread());
1329         assertTrue(s.hasQueuedPredecessors());
1330         assertTrue(s.hasQueuedThreads());
1331         assertEquals(1, s.getQueueLength());










1332 
1333         s.pleaseThrow = true;






1334         thread.interrupt();
1335         s.release(1);
1336         awaitTermination(thread);










1337     }
1338 
1339 }


  22 
  23 /*
  24  * This file is available under and governed by the GNU General Public
  25  * License version 2 only, as published by the Free Software Foundation.
  26  * However, the following notice accompanied the original version of this
  27  * file:
  28  *
  29  * Written by Doug Lea with assistance from members of JCP JSR-166
  30  * Expert Group and released to the public domain, as explained at
  31  * http://creativecommons.org/publicdomain/zero/1.0/
  32  * Other contributors include Andrew Wright, Jeffrey Hayes,
  33  * Pat Fisher, Mike Judd.
  34  */
  35 
  36 import static java.util.concurrent.TimeUnit.MILLISECONDS;
  37 import static java.util.concurrent.TimeUnit.NANOSECONDS;
  38 
  39 import java.util.Arrays;
  40 import java.util.Collection;
  41 import java.util.HashSet;
  42 import java.util.concurrent.atomic.AtomicBoolean;
  43 import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
  44 import java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject;
  45 
  46 import junit.framework.Test;
  47 import junit.framework.TestSuite;
  48 
  49 @SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
  50 public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase {
  51     public static void main(String[] args) {
  52         main(suite(), args);
  53     }
  54     public static Test suite() {
  55         return new TestSuite(AbstractQueuedLongSynchronizerTest.class);
  56     }
  57 
  58     /**
  59      * A simple mutex class, adapted from the class javadoc.  Exclusive
  60      * acquire tests exercise this as a sample user extension.
  61      *
  62      * Unlike the javadoc sample, we don't track owner thread via


1269         assertTrue(c.awaitNanos(0L) <= 0);
1270         assertFalse(c.await(0L, NANOSECONDS));
1271         sync.release();
1272     }
1273 
1274     /**
1275      * awaitNanos/timed await with maximum negative wait times does not underflow
1276      */
1277     public void testAwait_NegativeInfinity() throws InterruptedException {
1278         final Mutex sync = new Mutex();
1279         final ConditionObject c = sync.newCondition();
1280         sync.acquire();
1281         assertTrue(c.awaitNanos(Long.MIN_VALUE) <= 0);
1282         assertFalse(c.await(Long.MIN_VALUE, NANOSECONDS));
1283         sync.release();
1284     }
1285 
1286     /**
1287      * Tests scenario for
1288      * JDK-8191937: Lost interrupt in AbstractQueuedSynchronizer when tryAcquire methods throw
1289      * ant -Djsr166.tckTestClass=AbstractQueuedLongSynchronizerTest -Djsr166.methodFilter=testInterruptedFailingAcquire -Djsr166.runsPerTest=10000 tck
1290      */
1291     public void testInterruptedFailingAcquire() throws Throwable {
1292         class PleaseThrow extends RuntimeException {}
1293         final PleaseThrow ex = new PleaseThrow();
1294         final AtomicBoolean thrown = new AtomicBoolean();
1295 
1296         // A synchronizer only offering a choice of failure modes
1297         class Sync extends AbstractQueuedLongSynchronizer {
1298             volatile boolean pleaseThrow;
1299             void maybeThrow() {
1300                 if (pleaseThrow) {
1301                     // assert: tryAcquire methods can throw at most once
1302                     if (! thrown.compareAndSet(false, true))
1303                         throw new AssertionError();
1304                     throw ex;
1305                 }
1306             }
1307 
1308             @Override protected boolean tryAcquire(long ignored) {
1309                 maybeThrow();
1310                 return false;
1311             }
1312             @Override protected long tryAcquireShared(long ignored) {
1313                 maybeThrow();
1314                 return -1;
1315             }
1316             @Override protected boolean tryRelease(long ignored) {
1317                 return true;
1318             }
1319             @Override protected boolean tryReleaseShared(long ignored) {
1320                 return true;
1321             }
1322         }
1323 
1324         final Sync s = new Sync();
1325         final boolean acquireInterruptibly = randomBoolean();
1326         final Action[] uninterruptibleAcquireActions = {
1327             () -> s.acquire(1),
1328             () -> s.acquireShared(1),
1329         };
1330         final long nanosTimeout = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
1331         final Action[] interruptibleAcquireActions = {
1332             () -> s.acquireInterruptibly(1),
1333             () -> s.acquireSharedInterruptibly(1),
1334             () -> s.tryAcquireNanos(1, nanosTimeout),
1335             () -> s.tryAcquireSharedNanos(1, nanosTimeout),
1336         };
1337         final Action[] releaseActions = {
1338             () -> s.release(1),
1339             () -> s.releaseShared(1),
1340         };
1341         final Action acquireAction = acquireInterruptibly
1342             ? chooseRandomly(interruptibleAcquireActions)
1343             : chooseRandomly(uninterruptibleAcquireActions);
1344         final Action releaseAction
1345             = chooseRandomly(releaseActions);
1346 
1347         // From os_posix.cpp:
1348         //
1349         // NOTE that since there is no "lock" around the interrupt and
1350         // is_interrupted operations, there is the possibility that the
1351         // interrupted flag (in osThread) will be "false" but that the
1352         // low-level events will be in the signaled state. This is
1353         // intentional. The effect of this is that Object.wait() and
1354         // LockSupport.park() will appear to have a spurious wakeup, which
1355         // is allowed and not harmful, and the possibility is so rare that
1356         // it is not worth the added complexity to add yet another lock.
1357         final Thread thread = newStartedThread(new CheckedRunnable() {
1358             public void realRun() throws Throwable {
1359                 try {
1360                     acquireAction.run();



1361                     shouldThrow();
1362                 } catch (InterruptedException possible) {
1363                     assertTrue(acquireInterruptibly);
1364                     assertFalse(Thread.interrupted());
1365                 } catch (PleaseThrow possible) {
1366                     awaitInterrupted();
1367                 }
1368             }});
1369         for (long startTime = 0L;; ) {
1370             waitForThreadToEnterWaitState(thread);
1371             if (s.getFirstQueuedThread() == thread
1372                 && s.hasQueuedPredecessors()
1373                 && s.hasQueuedThreads()
1374                 && s.getQueueLength() == 1
1375                 && s.hasContended())
1376                 break;
1377             if (startTime == 0L)
1378                 startTime = System.nanoTime();
1379             else if (millisElapsedSince(startTime) > LONG_DELAY_MS)
1380                 fail("timed out waiting for AQS state: "
1381                      + "thread state=" + thread.getState()
1382                      + ", queued threads=" + s.getQueuedThreads());
1383             Thread.yield();
1384         }
1385 
1386         s.pleaseThrow = true;
1387         // release and interrupt, in random order
1388         if (randomBoolean()) {
1389             thread.interrupt();
1390             releaseAction.run();
1391         } else {
1392             releaseAction.run();
1393             thread.interrupt();
1394         }
1395         awaitTermination(thread);
1396 
1397         if (! acquireInterruptibly)
1398             assertTrue(thrown.get());
1399 
1400         assertNull(s.getFirstQueuedThread());
1401         assertFalse(s.hasQueuedPredecessors());
1402         assertFalse(s.hasQueuedThreads());
1403         assertEquals(0, s.getQueueLength());
1404         assertTrue(s.getQueuedThreads().isEmpty());
1405         assertTrue(s.hasContended());
1406     }
1407 
1408 }
< prev index next >