8231026: Miscellaneous changes imported from jsr166 CVS 2019-11
Reviewed-by: martin
This commit is contained in:
parent
dc7d30d08e
commit
f29d1d172b
@ -623,8 +623,8 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
final CompletableFuture<V> tryFire(int mode) {
|
final CompletableFuture<V> tryFire(int mode) {
|
||||||
CompletableFuture<V> d; CompletableFuture<T> a;
|
CompletableFuture<V> d; CompletableFuture<T> a;
|
||||||
Object r; Throwable x; Function<? super T,? extends V> f;
|
Object r; Throwable x; Function<? super T,? extends V> f;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ((a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null)
|
|| (d = dep) == null || (f = fn) == null)
|
||||||
return null;
|
return null;
|
||||||
tryComplete: if (d.result == null) {
|
tryComplete: if (d.result == null) {
|
||||||
if (r instanceof AltResult) {
|
if (r instanceof AltResult) {
|
||||||
@ -645,7 +645,7 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
d.completeThrowable(ex);
|
d.completeThrowable(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dep = null; src = null; fn = null;
|
src = null; dep = null; fn = null;
|
||||||
return d.postFire(a, mode);
|
return d.postFire(a, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -695,8 +695,8 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
final CompletableFuture<Void> tryFire(int mode) {
|
final CompletableFuture<Void> tryFire(int mode) {
|
||||||
CompletableFuture<Void> d; CompletableFuture<T> a;
|
CompletableFuture<Void> d; CompletableFuture<T> a;
|
||||||
Object r; Throwable x; Consumer<? super T> f;
|
Object r; Throwable x; Consumer<? super T> f;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ((a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null)
|
|| (d = dep) == null || (f = fn) == null)
|
||||||
return null;
|
return null;
|
||||||
tryComplete: if (d.result == null) {
|
tryComplete: if (d.result == null) {
|
||||||
if (r instanceof AltResult) {
|
if (r instanceof AltResult) {
|
||||||
@ -718,7 +718,7 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
d.completeThrowable(ex);
|
d.completeThrowable(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dep = null; src = null; fn = null;
|
src = null; dep = null; fn = null;
|
||||||
return d.postFire(a, mode);
|
return d.postFire(a, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -769,8 +769,8 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
final CompletableFuture<Void> tryFire(int mode) {
|
final CompletableFuture<Void> tryFire(int mode) {
|
||||||
CompletableFuture<Void> d; CompletableFuture<T> a;
|
CompletableFuture<Void> d; CompletableFuture<T> a;
|
||||||
Object r; Throwable x; Runnable f;
|
Object r; Throwable x; Runnable f;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ((a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null)
|
|| (d = dep) == null || (f = fn) == null)
|
||||||
return null;
|
return null;
|
||||||
if (d.result == null) {
|
if (d.result == null) {
|
||||||
if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
|
if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
|
||||||
@ -787,7 +787,7 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
d.completeThrowable(ex);
|
d.completeThrowable(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dep = null; src = null; fn = null;
|
src = null; dep = null; fn = null;
|
||||||
return d.postFire(a, mode);
|
return d.postFire(a, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -832,11 +832,11 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
final CompletableFuture<T> tryFire(int mode) {
|
final CompletableFuture<T> tryFire(int mode) {
|
||||||
CompletableFuture<T> d; CompletableFuture<T> a;
|
CompletableFuture<T> d; CompletableFuture<T> a;
|
||||||
Object r; BiConsumer<? super T, ? super Throwable> f;
|
Object r; BiConsumer<? super T, ? super Throwable> f;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ((a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null
|
|| (d = dep) == null || (f = fn) == null
|
||||||
|| !d.uniWhenComplete(r, f, mode > 0 ? null : this))
|
|| !d.uniWhenComplete(r, f, mode > 0 ? null : this))
|
||||||
return null;
|
return null;
|
||||||
dep = null; src = null; fn = null;
|
src = null; dep = null; fn = null;
|
||||||
return d.postFire(a, mode);
|
return d.postFire(a, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -902,11 +902,11 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
final CompletableFuture<V> tryFire(int mode) {
|
final CompletableFuture<V> tryFire(int mode) {
|
||||||
CompletableFuture<V> d; CompletableFuture<T> a;
|
CompletableFuture<V> d; CompletableFuture<T> a;
|
||||||
Object r; BiFunction<? super T, Throwable, ? extends V> f;
|
Object r; BiFunction<? super T, Throwable, ? extends V> f;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ((a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null
|
|| (d = dep) == null || (f = fn) == null
|
||||||
|| !d.uniHandle(r, f, mode > 0 ? null : this))
|
|| !d.uniHandle(r, f, mode > 0 ? null : this))
|
||||||
return null;
|
return null;
|
||||||
dep = null; src = null; fn = null;
|
src = null; dep = null; fn = null;
|
||||||
return d.postFire(a, mode);
|
return d.postFire(a, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -965,11 +965,11 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
final CompletableFuture<T> tryFire(int mode) {
|
final CompletableFuture<T> tryFire(int mode) {
|
||||||
CompletableFuture<T> d; CompletableFuture<T> a;
|
CompletableFuture<T> d; CompletableFuture<T> a;
|
||||||
Object r; Function<? super Throwable, ? extends T> f;
|
Object r; Function<? super Throwable, ? extends T> f;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ((a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null
|
|| (d = dep) == null || (f = fn) == null
|
||||||
|| !d.uniExceptionally(r, f, mode > 0 ? null : this))
|
|| !d.uniExceptionally(r, f, mode > 0 ? null : this))
|
||||||
return null;
|
return null;
|
||||||
dep = null; src = null; fn = null;
|
src = null; dep = null; fn = null;
|
||||||
return d.postFire(a, mode);
|
return d.postFire(a, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1024,8 +1024,8 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
CompletableFuture<T> d; CompletableFuture<T> a;
|
CompletableFuture<T> d; CompletableFuture<T> a;
|
||||||
Function<Throwable, ? extends CompletionStage<T>> f;
|
Function<Throwable, ? extends CompletionStage<T>> f;
|
||||||
Object r; Throwable x;
|
Object r; Throwable x;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ((a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null)
|
|| (d = dep) == null || (f = fn) == null)
|
||||||
return null;
|
return null;
|
||||||
if (d.result == null) {
|
if (d.result == null) {
|
||||||
if ((r instanceof AltResult) &&
|
if ((r instanceof AltResult) &&
|
||||||
@ -1048,7 +1048,7 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
else
|
else
|
||||||
d.internalComplete(r);
|
d.internalComplete(r);
|
||||||
}
|
}
|
||||||
dep = null; src = null; fn = null;
|
src = null; dep = null; fn = null;
|
||||||
return d.postFire(a, mode);
|
return d.postFire(a, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1086,8 +1086,8 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
}
|
}
|
||||||
final CompletableFuture<U> tryFire(int mode) {
|
final CompletableFuture<U> tryFire(int mode) {
|
||||||
CompletableFuture<U> d; CompletableFuture<T> a; Object r;
|
CompletableFuture<U> d; CompletableFuture<T> a; Object r;
|
||||||
if ((d = dep) == null
|
if ((a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null)
|
|| (d = dep) == null)
|
||||||
return null;
|
return null;
|
||||||
if (d.result == null)
|
if (d.result == null)
|
||||||
d.completeRelay(r);
|
d.completeRelay(r);
|
||||||
@ -1128,8 +1128,8 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
CompletableFuture<V> d; CompletableFuture<T> a;
|
CompletableFuture<V> d; CompletableFuture<T> a;
|
||||||
Function<? super T, ? extends CompletionStage<V>> f;
|
Function<? super T, ? extends CompletionStage<V>> f;
|
||||||
Object r; Throwable x;
|
Object r; Throwable x;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ((a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null)
|
|| (d = dep) == null || (f = fn) == null)
|
||||||
return null;
|
return null;
|
||||||
tryComplete: if (d.result == null) {
|
tryComplete: if (d.result == null) {
|
||||||
if (r instanceof AltResult) {
|
if (r instanceof AltResult) {
|
||||||
@ -1155,7 +1155,7 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
d.completeThrowable(ex);
|
d.completeThrowable(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dep = null; src = null; fn = null;
|
src = null; dep = null; fn = null;
|
||||||
return d.postFire(a, mode);
|
return d.postFire(a, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1270,12 +1270,12 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
CompletableFuture<T> a;
|
CompletableFuture<T> a;
|
||||||
CompletableFuture<U> b;
|
CompletableFuture<U> b;
|
||||||
Object r, s; BiFunction<? super T,? super U,? extends V> f;
|
Object r, s; BiFunction<? super T,? super U,? extends V> f;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ( (a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null
|
|
||||||
|| (b = snd) == null || (s = b.result) == null
|
|| (b = snd) == null || (s = b.result) == null
|
||||||
|
|| (d = dep) == null || (f = fn) == null
|
||||||
|| !d.biApply(r, s, f, mode > 0 ? null : this))
|
|| !d.biApply(r, s, f, mode > 0 ? null : this))
|
||||||
return null;
|
return null;
|
||||||
dep = null; src = null; snd = null; fn = null;
|
src = null; snd = null; dep = null; fn = null;
|
||||||
return d.postFire(a, b, mode);
|
return d.postFire(a, b, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1345,12 +1345,12 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
CompletableFuture<T> a;
|
CompletableFuture<T> a;
|
||||||
CompletableFuture<U> b;
|
CompletableFuture<U> b;
|
||||||
Object r, s; BiConsumer<? super T,? super U> f;
|
Object r, s; BiConsumer<? super T,? super U> f;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ( (a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null
|
|
||||||
|| (b = snd) == null || (s = b.result) == null
|
|| (b = snd) == null || (s = b.result) == null
|
||||||
|
|| (d = dep) == null || (f = fn) == null
|
||||||
|| !d.biAccept(r, s, f, mode > 0 ? null : this))
|
|| !d.biAccept(r, s, f, mode > 0 ? null : this))
|
||||||
return null;
|
return null;
|
||||||
dep = null; src = null; snd = null; fn = null;
|
src = null; snd = null; dep = null; fn = null;
|
||||||
return d.postFire(a, b, mode);
|
return d.postFire(a, b, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1421,12 +1421,12 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
CompletableFuture<T> a;
|
CompletableFuture<T> a;
|
||||||
CompletableFuture<U> b;
|
CompletableFuture<U> b;
|
||||||
Object r, s; Runnable f;
|
Object r, s; Runnable f;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ( (a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null
|
|
||||||
|| (b = snd) == null || (s = b.result) == null
|
|| (b = snd) == null || (s = b.result) == null
|
||||||
|
|| (d = dep) == null || (f = fn) == null
|
||||||
|| !d.biRun(r, s, f, mode > 0 ? null : this))
|
|| !d.biRun(r, s, f, mode > 0 ? null : this))
|
||||||
return null;
|
return null;
|
||||||
dep = null; src = null; snd = null; fn = null;
|
src = null; snd = null; dep = null; fn = null;
|
||||||
return d.postFire(a, b, mode);
|
return d.postFire(a, b, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1482,9 +1482,9 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
CompletableFuture<T> a;
|
CompletableFuture<T> a;
|
||||||
CompletableFuture<U> b;
|
CompletableFuture<U> b;
|
||||||
Object r, s, z; Throwable x;
|
Object r, s, z; Throwable x;
|
||||||
if ((d = dep) == null
|
if ( (a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null
|
|| (b = snd) == null || (s = b.result) == null
|
||||||
|| (b = snd) == null || (s = b.result) == null)
|
|| (d = dep) == null)
|
||||||
return null;
|
return null;
|
||||||
if (d.result == null) {
|
if (d.result == null) {
|
||||||
if ((r instanceof AltResult
|
if ((r instanceof AltResult
|
||||||
@ -1557,13 +1557,11 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
super(executor, dep, src, snd); this.fn = fn;
|
super(executor, dep, src, snd); this.fn = fn;
|
||||||
}
|
}
|
||||||
final CompletableFuture<V> tryFire(int mode) {
|
final CompletableFuture<V> tryFire(int mode) {
|
||||||
CompletableFuture<V> d;
|
CompletableFuture<V> d; CompletableFuture<? extends T> a, b;
|
||||||
CompletableFuture<T> a;
|
|
||||||
CompletableFuture<U> b;
|
|
||||||
Object r; Throwable x; Function<? super T,? extends V> f;
|
Object r; Throwable x; Function<? super T,? extends V> f;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ((a = src) == null || (b = snd) == null
|
||||||
|| (a = src) == null || (b = snd) == null
|
|| ((r = a.result) == null && (r = b.result) == null)
|
||||||
|| ((r = a.result) == null && (r = b.result) == null))
|
|| (d = dep) == null || (f = fn) == null)
|
||||||
return null;
|
return null;
|
||||||
tryComplete: if (d.result == null) {
|
tryComplete: if (d.result == null) {
|
||||||
try {
|
try {
|
||||||
@ -1582,7 +1580,7 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
d.completeThrowable(ex);
|
d.completeThrowable(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dep = null; src = null; snd = null; fn = null;
|
src = null; snd = null; dep = null; fn = null;
|
||||||
return d.postFire(a, b, mode);
|
return d.postFire(a, b, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1612,13 +1610,11 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
super(executor, dep, src, snd); this.fn = fn;
|
super(executor, dep, src, snd); this.fn = fn;
|
||||||
}
|
}
|
||||||
final CompletableFuture<Void> tryFire(int mode) {
|
final CompletableFuture<Void> tryFire(int mode) {
|
||||||
CompletableFuture<Void> d;
|
CompletableFuture<Void> d; CompletableFuture<? extends T> a, b;
|
||||||
CompletableFuture<T> a;
|
|
||||||
CompletableFuture<U> b;
|
|
||||||
Object r; Throwable x; Consumer<? super T> f;
|
Object r; Throwable x; Consumer<? super T> f;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ((a = src) == null || (b = snd) == null
|
||||||
|| (a = src) == null || (b = snd) == null
|
|| ((r = a.result) == null && (r = b.result) == null)
|
||||||
|| ((r = a.result) == null && (r = b.result) == null))
|
|| (d = dep) == null || (f = fn) == null)
|
||||||
return null;
|
return null;
|
||||||
tryComplete: if (d.result == null) {
|
tryComplete: if (d.result == null) {
|
||||||
try {
|
try {
|
||||||
@ -1638,7 +1634,7 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
d.completeThrowable(ex);
|
d.completeThrowable(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dep = null; src = null; snd = null; fn = null;
|
src = null; snd = null; dep = null; fn = null;
|
||||||
return d.postFire(a, b, mode);
|
return d.postFire(a, b, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1668,13 +1664,11 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
super(executor, dep, src, snd); this.fn = fn;
|
super(executor, dep, src, snd); this.fn = fn;
|
||||||
}
|
}
|
||||||
final CompletableFuture<Void> tryFire(int mode) {
|
final CompletableFuture<Void> tryFire(int mode) {
|
||||||
CompletableFuture<Void> d;
|
CompletableFuture<Void> d; CompletableFuture<?> a, b;
|
||||||
CompletableFuture<T> a;
|
|
||||||
CompletableFuture<U> b;
|
|
||||||
Object r; Throwable x; Runnable f;
|
Object r; Throwable x; Runnable f;
|
||||||
if ((d = dep) == null || (f = fn) == null
|
if ((a = src) == null || (b = snd) == null
|
||||||
|| (a = src) == null || (b = snd) == null
|
|| ((r = a.result) == null && (r = b.result) == null)
|
||||||
|| ((r = a.result) == null && (r = b.result) == null))
|
|| (d = dep) == null || (f = fn) == null)
|
||||||
return null;
|
return null;
|
||||||
if (d.result == null) {
|
if (d.result == null) {
|
||||||
try {
|
try {
|
||||||
@ -1691,7 +1685,7 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
d.completeThrowable(ex);
|
d.completeThrowable(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dep = null; src = null; snd = null; fn = null;
|
src = null; snd = null; dep = null; fn = null;
|
||||||
return d.postFire(a, b, mode);
|
return d.postFire(a, b, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1726,11 +1720,10 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||||||
CompletableFuture<Object> d; CompletableFuture<?> a;
|
CompletableFuture<Object> d; CompletableFuture<?> a;
|
||||||
CompletableFuture<?>[] as;
|
CompletableFuture<?>[] as;
|
||||||
Object r;
|
Object r;
|
||||||
if ((d = dep) == null
|
if ((a = src) == null || (r = a.result) == null
|
||||||
|| (a = src) == null || (r = a.result) == null
|
|| (d = dep) == null || (as = srcs) == null)
|
||||||
|| (as = srcs) == null)
|
|
||||||
return null;
|
return null;
|
||||||
dep = null; src = null; srcs = null;
|
src = null; dep = null; srcs = null;
|
||||||
if (d.completeRelay(r)) {
|
if (d.completeRelay(r)) {
|
||||||
for (CompletableFuture<?> b : as)
|
for (CompletableFuture<?> b : as)
|
||||||
if (b != a)
|
if (b != a)
|
||||||
|
@ -42,12 +42,17 @@ import static java.util.concurrent.locks.StampedLock.isWriteLockStamp;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.StampedLock;
|
import java.util.concurrent.locks.StampedLock;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
@ -102,56 +107,51 @@ public class StampedLockTest extends JSR166TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Action> lockLockers(Lock lock) {
|
List<Action> lockLockers(Lock lock) {
|
||||||
List<Action> lockers = new ArrayList<>();
|
return List.of(
|
||||||
lockers.add(() -> lock.lock());
|
() -> lock.lock(),
|
||||||
lockers.add(() -> lock.lockInterruptibly());
|
() -> lock.lockInterruptibly(),
|
||||||
lockers.add(() -> lock.tryLock());
|
() -> lock.tryLock(),
|
||||||
lockers.add(() -> lock.tryLock(Long.MIN_VALUE, DAYS));
|
() -> lock.tryLock(Long.MIN_VALUE, DAYS),
|
||||||
lockers.add(() -> lock.tryLock(0L, DAYS));
|
() -> lock.tryLock(0L, DAYS),
|
||||||
lockers.add(() -> lock.tryLock(Long.MAX_VALUE, DAYS));
|
() -> lock.tryLock(Long.MAX_VALUE, DAYS));
|
||||||
return lockers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Function<StampedLock, Long>> readLockers() {
|
List<Function<StampedLock, Long>> readLockers() {
|
||||||
List<Function<StampedLock, Long>> readLockers = new ArrayList<>();
|
return List.of(
|
||||||
readLockers.add(sl -> sl.readLock());
|
sl -> sl.readLock(),
|
||||||
readLockers.add(sl -> sl.tryReadLock());
|
sl -> sl.tryReadLock(),
|
||||||
readLockers.add(sl -> readLockInterruptiblyUninterrupted(sl));
|
sl -> readLockInterruptiblyUninterrupted(sl),
|
||||||
readLockers.add(sl -> tryReadLockUninterrupted(sl, Long.MIN_VALUE, DAYS));
|
sl -> tryReadLockUninterrupted(sl, Long.MIN_VALUE, DAYS),
|
||||||
readLockers.add(sl -> tryReadLockUninterrupted(sl, 0L, DAYS));
|
sl -> tryReadLockUninterrupted(sl, 0L, DAYS),
|
||||||
readLockers.add(sl -> sl.tryConvertToReadLock(sl.tryOptimisticRead()));
|
sl -> sl.tryConvertToReadLock(sl.tryOptimisticRead()));
|
||||||
return readLockers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<BiConsumer<StampedLock, Long>> readUnlockers() {
|
List<BiConsumer<StampedLock, Long>> readUnlockers() {
|
||||||
List<BiConsumer<StampedLock, Long>> readUnlockers = new ArrayList<>();
|
return List.of(
|
||||||
readUnlockers.add((sl, stamp) -> sl.unlockRead(stamp));
|
(sl, stamp) -> sl.unlockRead(stamp),
|
||||||
readUnlockers.add((sl, stamp) -> assertTrue(sl.tryUnlockRead()));
|
(sl, stamp) -> assertTrue(sl.tryUnlockRead()),
|
||||||
readUnlockers.add((sl, stamp) -> sl.asReadLock().unlock());
|
(sl, stamp) -> sl.asReadLock().unlock(),
|
||||||
readUnlockers.add((sl, stamp) -> sl.unlock(stamp));
|
(sl, stamp) -> sl.unlock(stamp),
|
||||||
readUnlockers.add((sl, stamp) -> assertValid(sl, sl.tryConvertToOptimisticRead(stamp)));
|
(sl, stamp) -> assertValid(sl, sl.tryConvertToOptimisticRead(stamp)));
|
||||||
return readUnlockers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Function<StampedLock, Long>> writeLockers() {
|
List<Function<StampedLock, Long>> writeLockers() {
|
||||||
List<Function<StampedLock, Long>> writeLockers = new ArrayList<>();
|
return List.of(
|
||||||
writeLockers.add(sl -> sl.writeLock());
|
sl -> sl.writeLock(),
|
||||||
writeLockers.add(sl -> sl.tryWriteLock());
|
sl -> sl.tryWriteLock(),
|
||||||
writeLockers.add(sl -> writeLockInterruptiblyUninterrupted(sl));
|
sl -> writeLockInterruptiblyUninterrupted(sl),
|
||||||
writeLockers.add(sl -> tryWriteLockUninterrupted(sl, Long.MIN_VALUE, DAYS));
|
sl -> tryWriteLockUninterrupted(sl, Long.MIN_VALUE, DAYS),
|
||||||
writeLockers.add(sl -> tryWriteLockUninterrupted(sl, 0L, DAYS));
|
sl -> tryWriteLockUninterrupted(sl, 0L, DAYS),
|
||||||
writeLockers.add(sl -> sl.tryConvertToWriteLock(sl.tryOptimisticRead()));
|
sl -> sl.tryConvertToWriteLock(sl.tryOptimisticRead()));
|
||||||
return writeLockers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<BiConsumer<StampedLock, Long>> writeUnlockers() {
|
List<BiConsumer<StampedLock, Long>> writeUnlockers() {
|
||||||
List<BiConsumer<StampedLock, Long>> writeUnlockers = new ArrayList<>();
|
return List.of(
|
||||||
writeUnlockers.add((sl, stamp) -> sl.unlockWrite(stamp));
|
(sl, stamp) -> sl.unlockWrite(stamp),
|
||||||
writeUnlockers.add((sl, stamp) -> assertTrue(sl.tryUnlockWrite()));
|
(sl, stamp) -> assertTrue(sl.tryUnlockWrite()),
|
||||||
writeUnlockers.add((sl, stamp) -> sl.asWriteLock().unlock());
|
(sl, stamp) -> sl.asWriteLock().unlock(),
|
||||||
writeUnlockers.add((sl, stamp) -> sl.unlock(stamp));
|
(sl, stamp) -> sl.unlock(stamp),
|
||||||
writeUnlockers.add((sl, stamp) -> assertValid(sl, sl.tryConvertToOptimisticRead(stamp)));
|
(sl, stamp) -> assertValid(sl, sl.tryConvertToOptimisticRead(stamp)));
|
||||||
return writeUnlockers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1413,4 +1413,113 @@ public class StampedLockTest extends JSR166TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiple threads repeatedly contend for the same lock.
|
||||||
|
*/
|
||||||
|
public void testConcurrentAccess() throws Exception {
|
||||||
|
final StampedLock sl = new StampedLock();
|
||||||
|
final Lock wl = sl.asWriteLock();
|
||||||
|
final Lock rl = sl.asReadLock();
|
||||||
|
final long testDurationMillis = expensiveTests ? 1000 : 2;
|
||||||
|
final int nTasks = ThreadLocalRandom.current().nextInt(1, 10);
|
||||||
|
final AtomicBoolean done = new AtomicBoolean(false);
|
||||||
|
final List<CompletableFuture> futures = new ArrayList<>();
|
||||||
|
final List<Callable<Long>> stampedWriteLockers = List.of(
|
||||||
|
() -> sl.writeLock(),
|
||||||
|
() -> writeLockInterruptiblyUninterrupted(sl),
|
||||||
|
() -> tryWriteLockUninterrupted(sl, LONG_DELAY_MS, MILLISECONDS),
|
||||||
|
() -> {
|
||||||
|
long stamp;
|
||||||
|
do { stamp = sl.tryConvertToWriteLock(sl.tryOptimisticRead()); }
|
||||||
|
while (stamp == 0L);
|
||||||
|
return stamp;
|
||||||
|
},
|
||||||
|
() -> {
|
||||||
|
long stamp;
|
||||||
|
do { stamp = sl.tryWriteLock(); } while (stamp == 0L);
|
||||||
|
return stamp;
|
||||||
|
},
|
||||||
|
() -> {
|
||||||
|
long stamp;
|
||||||
|
do { stamp = sl.tryWriteLock(0L, DAYS); } while (stamp == 0L);
|
||||||
|
return stamp;
|
||||||
|
});
|
||||||
|
final List<Callable<Long>> stampedReadLockers = List.of(
|
||||||
|
() -> sl.readLock(),
|
||||||
|
() -> readLockInterruptiblyUninterrupted(sl),
|
||||||
|
() -> tryReadLockUninterrupted(sl, LONG_DELAY_MS, MILLISECONDS),
|
||||||
|
() -> {
|
||||||
|
long stamp;
|
||||||
|
do { stamp = sl.tryConvertToReadLock(sl.tryOptimisticRead()); }
|
||||||
|
while (stamp == 0L);
|
||||||
|
return stamp;
|
||||||
|
},
|
||||||
|
() -> {
|
||||||
|
long stamp;
|
||||||
|
do { stamp = sl.tryReadLock(); } while (stamp == 0L);
|
||||||
|
return stamp;
|
||||||
|
},
|
||||||
|
() -> {
|
||||||
|
long stamp;
|
||||||
|
do { stamp = sl.tryReadLock(0L, DAYS); } while (stamp == 0L);
|
||||||
|
return stamp;
|
||||||
|
});
|
||||||
|
final List<Consumer<Long>> stampedWriteUnlockers = List.of(
|
||||||
|
stamp -> sl.unlockWrite(stamp),
|
||||||
|
stamp -> sl.unlock(stamp),
|
||||||
|
stamp -> assertTrue(sl.tryUnlockWrite()),
|
||||||
|
stamp -> wl.unlock(),
|
||||||
|
stamp -> sl.tryConvertToOptimisticRead(stamp));
|
||||||
|
final List<Consumer<Long>> stampedReadUnlockers = List.of(
|
||||||
|
stamp -> sl.unlockRead(stamp),
|
||||||
|
stamp -> sl.unlock(stamp),
|
||||||
|
stamp -> assertTrue(sl.tryUnlockRead()),
|
||||||
|
stamp -> rl.unlock(),
|
||||||
|
stamp -> sl.tryConvertToOptimisticRead(stamp));
|
||||||
|
final Action writer = () -> {
|
||||||
|
// repeatedly acquires write lock
|
||||||
|
var locker = chooseRandomly(stampedWriteLockers);
|
||||||
|
var unlocker = chooseRandomly(stampedWriteUnlockers);
|
||||||
|
while (!done.getAcquire()) {
|
||||||
|
long stamp = locker.call();
|
||||||
|
try {
|
||||||
|
assertTrue(isWriteLockStamp(stamp));
|
||||||
|
assertTrue(sl.isWriteLocked());
|
||||||
|
assertFalse(isReadLockStamp(stamp));
|
||||||
|
assertFalse(sl.isReadLocked());
|
||||||
|
assertEquals(0, sl.getReadLockCount());
|
||||||
|
assertTrue(sl.validate(stamp));
|
||||||
|
} finally {
|
||||||
|
unlocker.accept(stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
final Action reader = () -> {
|
||||||
|
// repeatedly acquires read lock
|
||||||
|
var locker = chooseRandomly(stampedReadLockers);
|
||||||
|
var unlocker = chooseRandomly(stampedReadUnlockers);
|
||||||
|
while (!done.getAcquire()) {
|
||||||
|
long stamp = locker.call();
|
||||||
|
try {
|
||||||
|
assertFalse(isWriteLockStamp(stamp));
|
||||||
|
assertFalse(sl.isWriteLocked());
|
||||||
|
assertTrue(isReadLockStamp(stamp));
|
||||||
|
assertTrue(sl.isReadLocked());
|
||||||
|
assertTrue(sl.getReadLockCount() > 0);
|
||||||
|
assertTrue(sl.validate(stamp));
|
||||||
|
} finally {
|
||||||
|
unlocker.accept(stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (int i = nTasks; i--> 0; ) {
|
||||||
|
Action task = chooseRandomly(writer, reader);
|
||||||
|
futures.add(CompletableFuture.runAsync(checkedRunnable(task)));
|
||||||
|
}
|
||||||
|
Thread.sleep(testDurationMillis);
|
||||||
|
done.setRelease(true);
|
||||||
|
for (var future : futures)
|
||||||
|
checkTimedGet(future, null);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user