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

Comparing jsr166/src/test/tck/StampedLockTest.java (file contents):
Revision 1.36 by jsr166, Mon May 29 19:15:03 2017 UTC vs.
Revision 1.42 by jsr166, Mon Nov 27 23:38:11 2017 UTC

# Line 7 | Line 7
7  
8   import static java.util.concurrent.TimeUnit.DAYS;
9   import static java.util.concurrent.TimeUnit.MILLISECONDS;
10 < import static java.util.concurrent.TimeUnit.SECONDS;
10 >
11 > import static java.util.concurrent.locks.StampedLock.isLockStamp;
12 > import static java.util.concurrent.locks.StampedLock.isOptimisticReadStamp;
13 > import static java.util.concurrent.locks.StampedLock.isReadLockStamp;
14 > import static java.util.concurrent.locks.StampedLock.isWriteLockStamp;
15  
16   import java.util.ArrayList;
17   import java.util.List;
# Line 583 | Line 587 | public class StampedLockTest extends JSR
587          long s = lock.readLock();
588          Thread t = newStartedThread(new CheckedRunnable() {
589              public void realRun() {
590 <                threadAssertEquals(0L, lock.tryWriteLock());
590 >                assertEquals(0L, lock.tryWriteLock());
591              }});
592  
593          awaitTermination(t);
# Line 1181 | Line 1185 | public class StampedLockTest extends JSR
1185          }
1186          assertUnlocked(lock);
1187      }
1188 +
1189 +    /**
1190 +     * Stamped locks are not reentrant.
1191 +     */
1192 +    public void testNonReentrant() throws InterruptedException {
1193 +        final StampedLock lock = new StampedLock();
1194 +        long stamp;
1195 +
1196 +        stamp = lock.writeLock();
1197 +        assertValid(lock, stamp);
1198 +        assertEquals(0L, lock.tryWriteLock(0L, DAYS));
1199 +        assertEquals(0L, lock.tryReadLock(0L, DAYS));
1200 +        assertValid(lock, stamp);
1201 +        lock.unlockWrite(stamp);
1202 +
1203 +        stamp = lock.tryWriteLock(1L, DAYS);
1204 +        assertEquals(0L, lock.tryWriteLock(0L, DAYS));
1205 +        assertValid(lock, stamp);
1206 +        lock.unlockWrite(stamp);
1207 +
1208 +        stamp = lock.readLock();
1209 +        assertEquals(0L, lock.tryWriteLock(0L, DAYS));
1210 +        assertValid(lock, stamp);
1211 +        lock.unlockRead(stamp);
1212 +    }
1213 +
1214 +    /**
1215 +     * """StampedLocks have no notion of ownership. Locks acquired in
1216 +     * one thread can be released or converted in another."""
1217 +     */
1218 +    public void testNoOwnership() throws Throwable {
1219 +        ArrayList<Future<?>> futures = new ArrayList<>();
1220 +        for (Function<StampedLock, Long> writeLocker : writeLockers())
1221 +        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
1222 +            StampedLock lock = new StampedLock();
1223 +            long stamp = writeLocker.apply(lock);
1224 +            futures.add(cachedThreadPool.submit(new CheckedRunnable() {
1225 +                public void realRun() {
1226 +                    writeUnlocker.accept(lock, stamp);
1227 +                    assertUnlocked(lock);
1228 +                    assertFalse(lock.validate(stamp));
1229 +                }}));
1230 +        }
1231 +        for (Future<?> future : futures)
1232 +            assertNull(future.get());
1233 +    }
1234 +
1235 +    /** Tries out sample usage code from StampedLock javadoc. */
1236 +    public void testSampleUsage() throws Throwable {
1237 +        class Point {
1238 +            private double x, y;
1239 +            private final StampedLock sl = new StampedLock();
1240 +
1241 +            void move(double deltaX, double deltaY) { // an exclusively locked method
1242 +                long stamp = sl.writeLock();
1243 +                try {
1244 +                    x += deltaX;
1245 +                    y += deltaY;
1246 +                } finally {
1247 +                    sl.unlockWrite(stamp);
1248 +                }
1249 +            }
1250 +
1251 +            double distanceFromOrigin() { // A read-only method
1252 +                double currentX, currentY;
1253 +                long stamp = sl.tryOptimisticRead();
1254 +                do {
1255 +                    if (stamp == 0L)
1256 +                        stamp = sl.readLock();
1257 +                    try {
1258 +                        // possibly racy reads
1259 +                        currentX = x;
1260 +                        currentY = y;
1261 +                    } finally {
1262 +                        stamp = sl.tryConvertToOptimisticRead(stamp);
1263 +                    }
1264 +                } while (stamp == 0);
1265 +                return Math.hypot(currentX, currentY);
1266 +            }
1267 +
1268 +            double distanceFromOrigin2() {
1269 +                long stamp = sl.tryOptimisticRead();
1270 +                try {
1271 +                    retryHoldingLock:
1272 +                    for (;; stamp = sl.readLock()) {
1273 +                        if (stamp == 0L)
1274 +                            continue retryHoldingLock;
1275 +                        // possibly racy reads
1276 +                        double currentX = x;
1277 +                        double currentY = y;
1278 +                        if (!sl.validate(stamp))
1279 +                            continue retryHoldingLock;
1280 +                        return Math.hypot(currentX, currentY);
1281 +                    }
1282 +                } finally {
1283 +                    if (StampedLock.isReadLockStamp(stamp))
1284 +                        sl.unlockRead(stamp);
1285 +                }
1286 +            }
1287 +
1288 +            void moveIfAtOrigin(double newX, double newY) {
1289 +                long stamp = sl.readLock();
1290 +                try {
1291 +                    while (x == 0.0 && y == 0.0) {
1292 +                        long ws = sl.tryConvertToWriteLock(stamp);
1293 +                        if (ws != 0L) {
1294 +                            stamp = ws;
1295 +                            x = newX;
1296 +                            y = newY;
1297 +                            return;
1298 +                        }
1299 +                        else {
1300 +                            sl.unlockRead(stamp);
1301 +                            stamp = sl.writeLock();
1302 +                        }
1303 +                    }
1304 +                } finally {
1305 +                    sl.unlock(stamp);
1306 +                }
1307 +            }
1308 +        }
1309 +
1310 +        Point p = new Point();
1311 +        p.move(3.0, 4.0);
1312 +        assertEquals(5.0, p.distanceFromOrigin());
1313 +        p.moveIfAtOrigin(5.0, 12.0);
1314 +        assertEquals(5.0, p.distanceFromOrigin2());
1315 +    }
1316 +
1317 +    /**
1318 +     * Stamp inspection methods work as expected, and do not inspect
1319 +     * the state of the lock itself.
1320 +     */
1321 +    public void testStampStateInspectionMethods() {
1322 +        StampedLock lock = new StampedLock();
1323 +
1324 +        assertFalse(isWriteLockStamp(0L));
1325 +        assertFalse(isReadLockStamp(0L));
1326 +        assertFalse(isLockStamp(0L));
1327 +        assertFalse(isOptimisticReadStamp(0L));
1328 +
1329 +        {
1330 +            long stamp = lock.writeLock();
1331 +            for (int i = 0; i < 2; i++) {
1332 +                assertTrue(isWriteLockStamp(stamp));
1333 +                assertFalse(isReadLockStamp(stamp));
1334 +                assertTrue(isLockStamp(stamp));
1335 +                assertFalse(isOptimisticReadStamp(stamp));
1336 +                if (i == 0)
1337 +                    lock.unlockWrite(stamp);
1338 +            }
1339 +        }
1340 +
1341 +        {
1342 +            long stamp = lock.readLock();
1343 +            for (int i = 0; i < 2; i++) {
1344 +                assertFalse(isWriteLockStamp(stamp));
1345 +                assertTrue(isReadLockStamp(stamp));
1346 +                assertTrue(isLockStamp(stamp));
1347 +                assertFalse(isOptimisticReadStamp(stamp));
1348 +                if (i == 0)
1349 +                    lock.unlockRead(stamp);
1350 +            }
1351 +        }
1352 +
1353 +        {
1354 +            long optimisticStamp = lock.tryOptimisticRead();
1355 +            long readStamp = lock.tryConvertToReadLock(optimisticStamp);
1356 +            long writeStamp = lock.tryConvertToWriteLock(readStamp);
1357 +            for (int i = 0; i < 2; i++) {
1358 +                assertFalse(isWriteLockStamp(optimisticStamp));
1359 +                assertFalse(isReadLockStamp(optimisticStamp));
1360 +                assertFalse(isLockStamp(optimisticStamp));
1361 +                assertTrue(isOptimisticReadStamp(optimisticStamp));
1362 +
1363 +                assertFalse(isWriteLockStamp(readStamp));
1364 +                assertTrue(isReadLockStamp(readStamp));
1365 +                assertTrue(isLockStamp(readStamp));
1366 +                assertFalse(isOptimisticReadStamp(readStamp));
1367 +
1368 +                assertTrue(isWriteLockStamp(writeStamp));
1369 +                assertFalse(isReadLockStamp(writeStamp));
1370 +                assertTrue(isLockStamp(writeStamp));
1371 +                assertFalse(isOptimisticReadStamp(writeStamp));
1372 +                if (i == 0)
1373 +                    lock.unlockWrite(writeStamp);
1374 +            }
1375 +        }
1376 +    }
1377 +
1378   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines