1293 */
1294 public void testCancelCancelRace() throws InterruptedException {
1295 class Sync extends AbstractQueuedSynchronizer {
1296 protected boolean tryAcquire(int acquires) {
1297 return !hasQueuedPredecessors() && compareAndSetState(0, 1);
1298 }
1299 protected boolean tryRelease(int releases) {
1300 return compareAndSetState(1, 0);
1301 }
1302 }
1303
1304 Sync s = new Sync();
1305 s.acquire(1); // acquire to force other threads to enqueue
1306
1307 // try to trigger double cancel race with two background threads
1308 ArrayList<Thread> threads = new ArrayList<>();
1309 Runnable failedAcquire = () -> {
1310 try {
1311 s.acquireInterruptibly(1);
1312 shouldThrow();
1313 } catch (InterruptedException expected) {}
1314 };
1315 for (int i = 0; i < 2; i++) {
1316 Thread thread = new Thread(failedAcquire);
1317 thread.start();
1318 threads.add(thread);
1319 }
1320 Thread.sleep(100);
1321 for (Thread thread : threads) thread.interrupt();
1322 for (Thread thread : threads) awaitTermination(thread);
1323
1324 s.release(1);
1325
1326 // no one holds lock now, we should be able to acquire
1327 if (!s.tryAcquire(1))
1328 throw new RuntimeException(
1329 String.format(
1330 "Broken: hasQueuedPredecessors=%s hasQueuedThreads=%s queueLength=%d firstQueuedThread=%s",
1331 s.hasQueuedPredecessors(),
1332 s.hasQueuedThreads(),
1333 s.getQueueLength(),
|
1293 */
1294 public void testCancelCancelRace() throws InterruptedException {
1295 class Sync extends AbstractQueuedSynchronizer {
1296 protected boolean tryAcquire(int acquires) {
1297 return !hasQueuedPredecessors() && compareAndSetState(0, 1);
1298 }
1299 protected boolean tryRelease(int releases) {
1300 return compareAndSetState(1, 0);
1301 }
1302 }
1303
1304 Sync s = new Sync();
1305 s.acquire(1); // acquire to force other threads to enqueue
1306
1307 // try to trigger double cancel race with two background threads
1308 ArrayList<Thread> threads = new ArrayList<>();
1309 Runnable failedAcquire = () -> {
1310 try {
1311 s.acquireInterruptibly(1);
1312 shouldThrow();
1313 } catch (InterruptedException success) {}
1314 };
1315 for (int i = 0; i < 2; i++) {
1316 Thread thread = new Thread(failedAcquire);
1317 thread.start();
1318 threads.add(thread);
1319 }
1320 Thread.sleep(100);
1321 for (Thread thread : threads) thread.interrupt();
1322 for (Thread thread : threads) awaitTermination(thread);
1323
1324 s.release(1);
1325
1326 // no one holds lock now, we should be able to acquire
1327 if (!s.tryAcquire(1))
1328 throw new RuntimeException(
1329 String.format(
1330 "Broken: hasQueuedPredecessors=%s hasQueuedThreads=%s queueLength=%d firstQueuedThread=%s",
1331 s.hasQueuedPredecessors(),
1332 s.hasQueuedThreads(),
1333 s.getQueueLength(),
|