909 |
|
} |
910 |
|
} |
911 |
|
|
912 |
+ |
void runAsync(Runnable r1, Runnable r2) { |
913 |
+ |
boolean b = ThreadLocalRandom.current().nextBoolean(); |
914 |
+ |
CompletableFuture<Void> f1 = CompletableFuture.runAsync(b ? r1 : r2); |
915 |
+ |
CompletableFuture<Void> f2 = CompletableFuture.runAsync(b ? r2 : r1); |
916 |
+ |
f1.join(); |
917 |
+ |
f2.join(); |
918 |
+ |
} |
919 |
+ |
|
920 |
|
/** |
921 |
|
* Non-traversing Deque operations are linearizable. |
922 |
|
* https://bugs.openjdk.java.net/browse/JDK-8188900 |
940 |
|
x, nulls.sum(), zeros.sum())); |
941 |
|
}; |
942 |
|
|
943 |
< |
Runnable adder = () -> { |
936 |
< |
d.addFirst(0); |
937 |
< |
d.addLast(42); |
938 |
< |
}; |
943 |
> |
Runnable adder = () -> { d.addFirst(0); d.addLast(42); }; |
944 |
|
|
945 |
< |
boolean b = rnd.nextBoolean(); |
941 |
< |
Runnable r1 = b ? getter : adder; |
942 |
< |
Runnable r2 = b ? adder : getter; |
943 |
< |
CompletableFuture<Void> f1 = CompletableFuture.runAsync(r1); |
944 |
< |
CompletableFuture<Void> f2 = CompletableFuture.runAsync(r2); |
945 |
< |
f1.join(); |
946 |
< |
f2.join(); |
945 |
> |
runAsync(getter, adder); |
946 |
|
} |
947 |
|
} |
948 |
|
|
967 |
|
x, nulls.sum(), zeros.sum())); |
968 |
|
}; |
969 |
|
|
970 |
< |
Runnable adder = () -> { |
971 |
< |
d.addLast(0); |
972 |
< |
d.addFirst(42); |
973 |
< |
}; |
970 |
> |
Runnable adder = () -> { d.addLast(0); d.addFirst(42); }; |
971 |
> |
|
972 |
> |
runAsync(getter, adder); |
973 |
> |
} |
974 |
> |
} |
975 |
> |
|
976 |
> |
<T> T chooseRandomly(T... choices) { |
977 |
> |
return choices[ThreadLocalRandom.current().nextInt(choices.length)]; |
978 |
> |
} |
979 |
> |
|
980 |
> |
/** |
981 |
> |
* Non-traversing Deque operations (that return null) are linearizable. |
982 |
> |
* Don't return null when the deque is observably never empty. |
983 |
> |
* https://bugs.openjdk.java.net/browse/JDK-8189387 |
984 |
> |
* ant -Djsr166.expensiveTests=true -Djsr166.tckTestClass=ConcurrentLinkedDequeTest -Djsr166.methodFilter=testBug8189387 tck |
985 |
> |
*/ |
986 |
> |
public void testBug8189387() { |
987 |
> |
final ThreadLocalRandom rnd = ThreadLocalRandom.current(); |
988 |
> |
Object x = new Object(); |
989 |
> |
for (int n = expensiveTests ? 100_000 : 10; n--> 0; ) { |
990 |
> |
ConcurrentLinkedDeque<Object> d = new ConcurrentLinkedDeque<>(); |
991 |
> |
Runnable add = chooseRandomly( |
992 |
> |
() -> d.addFirst(x), |
993 |
> |
() -> d.offerFirst(x), |
994 |
> |
() -> d.addLast(x), |
995 |
> |
() -> d.offerLast(x)); |
996 |
> |
|
997 |
> |
Runnable get = chooseRandomly( |
998 |
> |
() -> assertFalse(d.isEmpty()), |
999 |
> |
() -> assertSame(x, d.peekFirst()), |
1000 |
> |
() -> assertSame(x, d.peekLast()), |
1001 |
> |
() -> assertSame(x, d.pollFirst()), |
1002 |
> |
() -> assertSame(x, d.pollLast())); |
1003 |
> |
|
1004 |
> |
Runnable addRemove = chooseRandomly( |
1005 |
> |
() -> { d.addFirst(x); d.pollLast(); }, |
1006 |
> |
() -> { d.offerFirst(x); d.removeFirst(); }, |
1007 |
> |
() -> { d.offerLast(x); d.removeLast(); }, |
1008 |
> |
() -> { d.addLast(x); d.pollFirst(); }); |
1009 |
|
|
1010 |
< |
boolean b = rnd.nextBoolean(); |
1011 |
< |
Runnable r1 = b ? getter : adder; |
978 |
< |
Runnable r2 = b ? adder : getter; |
979 |
< |
CompletableFuture<Void> f1 = CompletableFuture.runAsync(r1); |
980 |
< |
CompletableFuture<Void> f2 = CompletableFuture.runAsync(r2); |
981 |
< |
f1.join(); |
982 |
< |
f2.join(); |
1010 |
> |
add.run(); |
1011 |
> |
runAsync(get, addRemove); |
1012 |
|
} |
1013 |
|
} |
1014 |
|
} |