Java8并发新特性
Java8新增的并发API主要如下,内容是翻译的JDK1.8的官方文档,欢迎转载,转载请注明出处。
- ForkJoinPool.commonPool()
- ConcurrentHashMap(v8)
- ConcurrentHashMap.newKeySet()
- ConcurrentHashMap.newKeySet(int)
- CompletableFuture
- StampedLock
- LongAdder
- LongAccumulator
- DoubleAdder
- DoubleAccumulator
- CountedCompleter
- Executors.newWorkStealingPool()
- Executors.newWorkStealingPool(int)
- AtomicReference.getAndUpdate(UnaryOperator)
- AtomicReference.updateAndGet(UnaryOperator)
- AtomicReference.getAndAccumulate(V, UnaryOperator)
- AtomicReference.accumulateAndGet(V, UnaryOperator)
目录
1、AtomicReference.getAndUpdate. 2
2、AtomicReference.updateAndGet 2
3、AtomicReference.getAndAccumulate. 3
4、AtomicReference.accumulateAndGet 3
6、ConcurrentHashMap.reduceEntries. 4
7、ConcurrentHashMap.reduceEntriesToDouble. 4
8、ConcurrentHashMap.reduceEntriesToInt 4
9、ConcurrentHashMap.reduceEntriesToLong. 4
10、ConcurrentHashMap.reduceKeys. 4
11、ConcurrentHashMap.reduceKeysToDouble. 4
12、ConcurrentHashMap.reduceKeysToInt 5
13、ConcurrentHashMap.reduceKeysToLong. 5
14、ConcurrentHashMap.reduceToDouble. 5
15、ConcurrentHashMap.reduceToInt 5
16、ConcurrentHashMap.reduceToLong. 5
17、ConcurrentHashMap.reduceValues. 5
18、ConcurrentHashMap.reduceValuesToDouble. 6
19、ConcurrentHashMap.reduceValuesToInt 6
20、ConcurrentHashMap.reduceValuesToLong. 6
21、ConcurrentHashMap.search. 6
22、ConcurrentHashMap.searchEntries. 6
23、ConcurrentHashMap.searchKeys. 6
24、ConcurrentHashMap.searchValues. 6
25、ConcurrentHashMap.forEach. 7
26、ConcurrentHashMap.forEachEntry. 7
27、ConcurrentHashMap.forEachKey. 7
28、ConcurrentHashMap.forEachValue. 7
29、ConcurrentHashMap.newKeySet 7
34、Executors.newWorkStealingPool 19
36、ForkJoinPool.getCommonPoolParallelism.. 20
1、AtomicReference.getAndUpdate
getAndUpdate(UnaryOperator<V> updateFunction)
用应用给定函数的结果原子更新当前值,返回上一个值。
public final V getAndUpdate(UnaryOperator<V> updateFunction)用应用给定函数的结果原子更新当前值,返回上一个值。 该功能应该是无副作用的,因为尝试的更新由于线程之间的争用而失败时可能会被重新应用。
参数
updateFunction - 无副作用的功能
结果
以前的值
2、AtomicReference.updateAndGet
updateAndGet(UnaryOperator<V> updateFunction)
使用给定函数的结果原子更新当前值,返回更新的值。
public final V updateAndGet(UnaryOperator<V> updateFunction)使用给定函数的结果原子更新当前值,返回更新的值。 该功能应该是无副作用的,因为尝试的更新由于线程之间的争用而失败时可能会被重新应用。
参数
updateFunction - 无副作用的功能
结果
更新的值
3、AtomicReference.getAndAccumulate
getAndAccumulate(V x, BinaryOperator<V> accumulatorFunction)
使用给定函数应用给当前值和给定值的结果原子更新当前值,返回上一个值。
public final V getAndAccumulate(V x, BinaryOperator<V> accumulatorFunction)使用给定函数应用给当前值和给定值的结果原子更新当前值,返回上一个值。 该功能应该是无副作用的,因为尝试的更新由于线程之间的争用而失败时可能会被重新应用。 该函数应用当前值作为其第一个参数,给定的更新作为第二个参数。
参数
x - 更新值
accumulatorFunction - 两个参数的无副作用的函数
结果
以前的值
4、AtomicReference.accumulateAndGet
accumulateAndGet(V x, BinaryOperator<V> accumulatorFunction)
使用将给定函数应用于当前值和给定值的结果原子更新当前值,返回更新后的值。
public final V accumulateAndGet(V x,BinaryOperator<V> accumulatorFunction)使用将给定函数应用于当前值和给定值的结果原子更新当前值,返回更新后的值。 该功能应该是无副作用的,因为尝试的更新由于线程之间的争用而失败时可能会被重新应用。 该函数应用当前值作为其第一个参数,给定的更新作为第二个参数。
参数
x - 更新值
accumulatorFunction - 两个参数的无副作用函数
结果
更新的值
5、ConcurrentHashMap.reduce
reduce(long parallelismThreshold, BiFunction<? super K,? super V,? extends U> transformer, BiFunction<? super U,? super U,? extends U> reducer)
返回使用给定的reducer将所有(key,value)对的给定变换累加到组合值的结果,如果没有则返回null。
6、ConcurrentHashMap.reduceEntries
reduceEntries(long parallelismThreshold, BiFunction<Map.Entry<K,V>,Map.Entry<K,V>,? extends Map.Entry<K,V>> reducer)
返回使用给定的reducer累加所有条目的结果,以组合值,如果没有则返回null。
7、ConcurrentHashMap.reduceEntriesToDouble
reduceEntriesToDouble(long parallelismThreshold, ToDoubleFunction<Map.Entry<K,V>> transformer, double basis, DoubleBinaryOperator reducer)
返回使用给定的reducer累加给定变换的结果,以组合值,给定基础作为一个标识值。
8、ConcurrentHashMap.reduceEntriesToInt
reduceEntriesToInt(long parallelismThreshold, ToIntFunction<Map.Entry<K,V>> transformer, int basis, IntBinaryOperator reducer)
返回使用给定的reducer累加给定变换的结果,以组合值,给定基础作为一个标识值。
9、ConcurrentHashMap.reduceEntriesToLong
reduceEntriesToLong(long parallelismThreshold, ToLongFunction<Map.Entry<K,V>> transformer, long basis, LongBinaryOperator reducer)
返回使用给定的reducer累加给定变换的结果,以组合值,给定基础作为一个标识值。
10、ConcurrentHashMap.reduceKeys
reduceKeys(long parallelismThreshold, BiFunction<? super K,? super K,? extends K> reducer)
返回使用给定的reducer累加所有键的结果,以组合值,如果没有则返回null。
11、ConcurrentHashMap.reduceKeysToDouble
reduceKeysToDouble(long parallelismThreshold, ToDoubleFunction<? super K> transformer, double basis, DoubleBinaryOperator reducer)
返回使用给定的reducer累加所有键的给定变换的结果,以组合值,给定基础作为标识值。
12、ConcurrentHashMap.reduceKeysToInt
reduceKeysToInt(long parallelismThreshold, ToIntFunction<? super K> transformer, int basis, IntBinaryOperator reducer)
返回使用给定的reducer累加所有键的给定变换的结果,以组合值,给定基础作为标识值。
13、ConcurrentHashMap.reduceKeysToLong
reduceKeysToLong(long parallelismThreshold, ToLongFunction<? super K> transformer, long basis, LongBinaryOperator reducer)
返回使用给定的reducer累加所有键的给定变换的结果,以组合值,给定基础作为标识值。
14、ConcurrentHashMap.reduceToDouble
reduceToDouble(long parallelismThreshold, ToDoubleBiFunction<? super K,? super V> transformer, double basis, DoubleBinaryOperator reducer)
返回使用给定的reducer将所有(key,value)对的给定变换累加到结合值的结果,给定的基数作为一个标识值。
15、ConcurrentHashMap.reduceToInt
reduceToInt(long parallelismThreshold, ToIntBiFunction<? super K,? super V> transformer, int basis, IntBinaryOperator reducer)
返回使用给定的reducer将所有(key,value)对的给定变换累加到结合值的结果,给定的基数作为一个标识值。
16、ConcurrentHashMap.reduceToLong
reduceToLong(long parallelismThreshold, ToLongBiFunction<? super K,? super V> transformer, long basis, LongBinaryOperator reducer)
返回使用给定的reducer将所有(key,value)对的给定变换累加到结合值的结果,给定的基数作为一个标识值。
17、ConcurrentHashMap.reduceValues
reduceValues(long parallelismThreshold, BiFunction<? super V,? super V,? extends V> reducer)
返回使用给定的reducer累加所有值的结果,以组合值,如果没有则返回null。
reduceValues(long parallelismThreshold, Function<? super V,? extends U> transformer, BiFunction<? super U,? super U,? extends U> reducer)
返回使用给定的reducer累加所有值的给定变换以组合值的结果,否则返回null。
18、ConcurrentHashMap.reduceValuesToDouble
reduceValuesToDouble(long parallelismThreshold, ToDoubleFunction<? super V> transformer, double basis, DoubleBinaryOperator reducer)
返回使用给定的reducer累加所有值的给定变换的结果,以组合值,给定基础作为标识值。
19、ConcurrentHashMap.reduceValuesToInt
reduceValuesToInt(long parallelismThreshold, ToIntFunction<? super V> transformer, int basis, IntBinaryOperator reducer)
返回使用给定的reducer累加所有值的给定变换的结果,以组合值,给定基础作为标识值。
20、ConcurrentHashMap.reduceValuesToLong
reduceValuesToLong(long parallelismThreshold, ToLongFunction<? super V> transformer, long basis, LongBinaryOperator reducer)
返回使用给定的reducer累加所有值的给定变换的结果,以组合值,给定基础作为标识值。
21、ConcurrentHashMap.search
search(long parallelismThreshold, BiFunction<? super K,? super V,? extends U> searchFunction)
通过在每个(键,值)上应用给定的搜索函数返回非空结果,如果没有则返回null。
22、ConcurrentHashMap.searchEntries
searchEntries(long parallelismThreshold, Function<Map.Entry<K,V>,? extends U> searchFunction)
返回一个非空结果,从每个条目应用给定的搜索函数,如果没有,则返回null。
23、ConcurrentHashMap.searchKeys
searchKeys(long parallelismThreshold, Function<? super K,? extends U> searchFunction)
返回一个非空结果,在每个键上应用给定的搜索功能,如果没有,返回null。
24、ConcurrentHashMap.searchValues
searchValues(long parallelismThreshold, Function<? super V,? extends U> searchFunction)
返回一个非空结果,对每个值应用给定的搜索函数,如果没有,返回null。
25、ConcurrentHashMap.forEach
forEach(BiConsumer<? super K,? super V> action)
对此映射中的每个条目执行给定的操作,直到所有条目都被处理或操作引发异常。
26、ConcurrentHashMap.forEachEntry
forEachEntry(long parallelismThreshold, Consumer<? super Map.Entry<K,V>> action)
对每个条目执行给定的操作。
forEachEntry(long parallelismThreshold, Function<Map.Entry<K,V>,? extends U> transformer, Consumer<? super U> action)
对每个条目的每个非空变换执行给定的操作。
27、ConcurrentHashMap.forEachKey
forEachKey(long parallelismThreshold, Consumer<? super K> action)
对每个键执行给定的动作。
forEachKey(long parallelismThreshold, Function<? super K,? extends U> transformer, Consumer<? super U> action)
对每个键的每个非空变换执行给定的动作。
28、ConcurrentHashMap.forEachValue
forEachValue(long parallelismThreshold, Consumer<? super V> action)
对每个值执行给定的操作。
forEachValue(long parallelismThreshold, Function<? super V,? extends U> transformer, Consumer<? super U> action)
对每个值的每个非空转换执行给定的动作。
29、ConcurrentHashMap.newKeySet
newKeySet()
创建一个新的Set支持的ConcurrentHashMap从给定的类型到Boolean.TRUE 。
newKeySet(int initialCapacity)
创建一个新的Set支持的ConcurrentHashMap从给定的类型到Boolean.TRUE 。
30、CompletableFuture
public class CompletableFuture<T> extends Object implements Future<T>, CompletionStage<T>甲Future可以明确地完成(设定其值和状态),并且可以被用作CompletionStage ,支持有关的功能和它的完成时触发动作。
当两个或多个线程试图complete , completeExceptionally ,或cancel一个CompletableFuture,只有一个成功。
除了直接操作状态和结果的这些和相关方法外,CompletableFuture还实现了接口CompletionStage ,具有以下策略:
为异步方法的依赖完成提供的操作可以由完成当前CompletableFuture的线程或完成方法的任何其他调用者执行。
所有不使用显式Executor参数的异步方法都使用ForkJoinPool.commonPool()执行 (除非它不支持至少两个并行级别,在这种情况下,使用新的线程)。 为了简化监视,调试和跟踪,所有生成的异步任务都是标记接口CompletableFuture.AsynchronousCompletionTask的实例 。
所有CompletionStage方法都是独立于其他公共方法实现的,因此一个方法的行为不会受到子类中其他方法的覆盖的影响。
CompletableFuture还实施Future ,具有以下政策:
由于(不同于FutureTask ),这个类不能直接控制导致其完成的计算,所以取消被视为另一种形式的异常完成。 方法cancel具有相同的效果completeExceptionally(new CancellationException()) 。 方法isCompletedExceptionally()可用于确定CompletableFuture是否以任何特殊方式完成。
如果使用CompletionException异常完成,方法get()和get(long, TimeUnit)将抛出与对应的CompletionException中保持的相同原因的ExecutionException。 为了简化大多数情况下的使用,此类还定义了方法join()和getNow(T) ,而是在这些情况下直接抛出CompletionException。
构造器:
Constructor and Description |
CompletableFuture() 创建一个新的不完整的CompletableFuture。 |
核心方法:
Modifier and Type | Method and Description |
CompletableFuture<Void> | acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action) 返回一个新的CompletionStage,当这个或另一个给定阶段正常完成时,执行相应的结果作为提供的操作的参数。 |
CompletableFuture<Void> | acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action) 返回一个新的CompletionStage,当这个或另一个给定阶段正常完成时,将使用此阶段的默认异步执行工具执行,其中相应的结果作为提供的操作的参数。 |
CompletableFuture<Void> | acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action, Executor executor) 返回一个新的CompletionStage,当这个或另一个给定阶段正常完成时,将使用提供的执行器执行,其中相应的结果作为参数提供给函数。 |
static CompletableFuture<Void> | allOf(CompletableFuture<?>... cfs) 返回一个新的CompletableFuture,当所有给定的CompletableFutures完成时,完成。 |
static CompletableFuture<Object> | anyOf(CompletableFuture<?>... cfs) 返回一个新的CompletableFuture,当任何一个给定的CompletableFutures完成时,完成相同的结果。 |
<U> CompletableFuture<U> | applyToEither(CompletionStage<? extends T> other, Function<? super T,U> fn) 返回一个新的CompletionStage,当这个或另一个给定阶段正常完成时,执行相应的结果作为提供的函数的参数。 |
<U> CompletableFuture<U> | applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T,U> fn) 返回一个新的CompletionStage,当这个或另一个给定阶段正常完成时,将使用此阶段的默认异步执行工具执行,其中相应的结果作为提供函数的参数。 |
<U> CompletableFuture<U> | applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T,U> fn, Executor executor) 返回一个新的CompletionStage,当这个或另一个给定阶段正常完成时,将使用提供的执行器执行,其中相应的结果作为参数提供给函数。 |
boolean | cancel(boolean mayInterruptIfRunning) 如果尚未完成,请使用CancellationException完成此CompletableFuture 。 |
boolean | complete(T value) 如果不是已经完成,将返回的值 get()种相关方法为给定值。 |
static <U> CompletableFuture<U> | completedFuture(U value) 返回已经使用给定值完成的新的CompletableFuture。 |
boolean | completeExceptionally(Throwable ex) 如果尚未完成,则调用 get()和相关方法来抛出给定的异常。 |
CompletableFuture<T> | exceptionally(Function<Throwable,? extends T> fn) 返回一个新的CompletableFuture,当CompletableFuture完成时完成,结果是异常触发此CompletableFuture的完成特殊功能的给定功能; 否则,如果此CompletableFuture正常完成,则返回的CompletableFuture也会以相同的值正常完成。 |
T | get() 等待这个未来完成的必要,然后返回结果。 |
T | get(long timeout, TimeUnit unit) 如果有必要等待这个未来完成的给定时间,然后返回其结果(如果有的话)。 |
T | getNow(T valueIfAbsent) 如果已完成,则返回结果值(或抛出任何遇到的异常),否则返回给定的值IfAbsent。 |
int | getNumberOfDependents() 返回完成等待完成此CompletableFuture的CompletableFutures的估计数。 |
<U> CompletableFuture<U> | handle(BiFunction<? super T,Throwable,? extends U> fn) 返回一个新的CompletionStage,当此阶段正常或异常完成时,将使用此阶段的结果和异常作为所提供函数的参数执行。 |
<U> CompletableFuture<U> | handleAsync(BiFunction<? super T,Throwable,? extends U> fn) 返回一个新的CompletionStage,当该阶段完成正常或异常时,将使用此阶段的默认异步执行工具执行,此阶段的结果和异常作为提供函数的参数。 |
<U> CompletableFuture<U> | handleAsync(BiFunction<? super T,Throwable,? extends U> fn, Executor executor) 返回一个新的CompletionStage,当此阶段完成正常或异常时,将使用提供的执行程序执行此阶段的结果和异常作为提供的函数的参数。 |
boolean | isCancelled() 如果此CompletableFuture在正常完成之前被取消,则返回 true 。 |
boolean | isCompletedExceptionally() 如果此CompletableFuture以任何方式完成异常完成,则返回 true 。 |
boolean | isDone() 退货 true如果以任何方式完成:通常,特别地,或通过取消。 |
T | join() 完成后返回结果值,如果完成异常,则返回(未检查)异常。 |
void | obtrudeException(Throwable ex) 强制导致后续调用方法 get()和相关方法抛出给定的异常,无论是否已经完成。 |
void | obtrudeValue(T value) 强制设置或重置随后方法返回的值 get()和相关方法,无论是否已经完成。 |
CompletableFuture<Void> | runAfterBoth(CompletionStage<?> other, Runnable action) 返回一个新的CompletionStage,当这个和另一个给定的阶段都正常完成时,执行给定的动作。 |
CompletableFuture<Void> | runAfterBothAsync(CompletionStage<?> other, Runnable action) 返回一个新的CompletionStage,当这个和另一个给定阶段正常完成时,使用此阶段的默认异步执行工具执行给定的操作。 |
CompletableFuture<Void> | runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor) 返回一个新CompletionStage,当这和其他特定阶段正常完成,使用附带的执行见执行给定的动作CompletionStage覆盖特殊的完成规则的文档。 |
CompletableFuture<Void> | runAfterEither(CompletionStage<?> other, Runnable action) 返回一个新的CompletionStage,当这个或另一个给定阶段正常完成时,执行给定的操作。 |
CompletableFuture<Void> | runAfterEitherAsync(CompletionStage<?> other, Runnable action) 返回一个新的CompletionStage,当这个或另一个给定阶段正常完成时,使用此阶段的默认异步执行工具执行给定的操作。 |
CompletableFuture<Void> | runAfterEitherAsync(CompletionStage<?> other, Runnable action, Executor executor) 返回一个新的CompletionStage,当这个或另一个给定阶段正常完成时,使用提供的执行器执行给定的操作。 |
static CompletableFuture<Void> | runAsync(Runnable runnable) 返回一个新的CompletableFuture,它在运行给定操作后由运行在 ForkJoinPool.commonPool()中的任务 异步完成。 |
static CompletableFuture<Void> | runAsync(Runnable runnable, Executor executor) 返回一个新的CompletableFuture,它在运行给定操作之后由在给定执行程序中运行的任务异步完成。 |
static <U> CompletableFuture<U> | supplyAsync(Supplier<U> supplier) 返回一个新的CompletableFuture,它通过在 ForkJoinPool.commonPool()中运行的任务与通过调用给定的供应商获得的值 异步完成。 |
static <U> CompletableFuture<U> | supplyAsync(Supplier<U> supplier, Executor executor) 返回一个新的CompletableFuture,由给定执行器中运行的任务异步完成,并通过调用给定的供应商获得的值。 |
CompletableFuture<Void> | thenAccept(Consumer<? super T> action) 返回一个新的CompletionStage,当此阶段正常完成时,将以该阶段的结果作为提供的操作的参数执行。 |
CompletableFuture<Void> | thenAcceptAsync(Consumer<? super T> action) 返回一个新的CompletionStage,当此阶段正常完成时,将使用此阶段的默认异步执行工具执行,此阶段的结果作为提供的操作的参数。 |
CompletableFuture<Void> | thenAcceptAsync(Consumer<? super T> action, Executor executor) 返回一个新的CompletionStage,当此阶段正常完成时,将使用提供的执行程序执行此阶段的结果作为提供的操作的参数。 |
<U> CompletableFuture<Void> | thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T,? super U> action) 返回一个新的CompletionStage,当这个和另一个给定的阶段都正常完成时,两个结果作为提供的操作的参数被执行。 |
<U> CompletableFuture<Void> | thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T,? super U> action) 返回一个新的CompletionStage,当这个和另一个给定阶段正常完成时,将使用此阶段的默认异步执行工具执行,其中两个结果作为提供的操作的参数。 |
<U> CompletableFuture<Void> | thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T,? super U> action, Executor executor) 返回一个新的CompletionStage,当这个和另一个给定阶段正常完成时,使用提供的执行器执行,其中两个结果作为提供的函数的参数。 |
<U> CompletableFuture<U> | thenApply(Function<? super T,? extends U> fn) 返回一个新的CompletionStage,当此阶段正常完成时,将以该阶段的结果作为所提供函数的参数执行。 |
<U> CompletableFuture<U> | thenApplyAsync(Function<? super T,? extends U> fn) 返回一个新的CompletionStage,当该阶段正常完成时,将使用此阶段的默认异步执行工具执行此阶段的结果作为所提供函数的参数。 |
<U> CompletableFuture<U> | thenApplyAsync(Function<? super T,? extends U> fn, Executor executor) 返回一个新的CompletionStage,当此阶段正常完成时,将使用提供的执行程序执行此阶段的结果作为提供函数的参数。 |
<U,V> CompletableFuture<V> | thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn) 返回一个新的CompletionStage,当这个和另一个给定的阶段都正常完成时,两个结果作为提供函数的参数执行。 |
<U,V> CompletableFuture<V> | thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn) 返回一个新的CompletionStage,当这个和另一个给定阶段正常完成时,将使用此阶段的默认异步执行工具执行,其中两个结果作为提供函数的参数。 |
<U,V> CompletableFuture<V> | thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor) 返回一个新的CompletionStage,当这个和另一个给定阶段正常完成时,使用提供的执行器执行,其中两个结果作为提供的函数的参数。 |
<U> CompletableFuture<U> | thenCompose(Function<? super T,? extends CompletionStage<U>> fn) 返回一个新的CompletionStage,当这个阶段正常完成时,这个阶段将作为提供函数的参数执行。 |
<U> CompletableFuture<U> | thenComposeAsync(Function<? super T,? extends CompletionStage<U>> fn) 返回一个新的CompletionStage,当此阶段正常完成时,将使用此阶段的默认异步执行工具执行,此阶段作为提供的函数的参数。 |
<U> CompletableFuture<U> | thenComposeAsync(Function<? super T,? extends CompletionStage<U>> fn, Executor executor) 返回一个新的CompletionStage,当此阶段正常完成时,将使用提供的执行程序执行此阶段的结果作为提供函数的参数。 |
CompletableFuture<Void> | thenRun(Runnable action) 返回一个新的CompletionStage,当此阶段正常完成时,执行给定的操作。 |
CompletableFuture<Void> | thenRunAsync(Runnable action) 返回一个新的CompletionStage,当此阶段正常完成时,使用此阶段的默认异步执行工具执行给定的操作。 |
CompletableFuture<Void> | thenRunAsync(Runnable action, Executor executor) 返回一个新的CompletionStage,当此阶段正常完成时,使用提供的执行程序执行给定的操作。 |
CompletableFuture<T> | toCompletableFuture() 返回此CompletableFuture |
String | toString() 返回一个标识此CompletableFuture的字符串及其完成状态。 |
CompletableFuture<T> | whenComplete(BiConsumer<? super T,? super Throwable> action) 返回与此阶段相同的结果或异常的新的CompletionStage,当此阶段完成时,使用结果(或 null如果没有))和此阶段的异常(或 null如果没有))执行给定的操作。 |
CompletableFuture<T> | whenCompleteAsync(BiConsumer<? super T,? super Throwable> action) 返回一个与此阶段相同结果或异常的新CompletionStage,当此阶段完成时,执行给定操作将使用此阶段的默认异步执行工具执行给定操作,结果(或 null如果没有))和异常(或 null如果没有)这个阶段作为参数。 |
CompletableFuture<T> | whenCompleteAsync(BiConsumer<? super T,? super Throwable> action, Executor executor) 返回与此阶段相同的结果或异常的新的CompletionStage,当此阶段完成时,使用提供的执行者执行给定的操作,如果没有,则使用结果(或 null如果没有))和异常(或 null如果没有))作为论据。 |
31、CountedCompleter
public abstract class CountedCompleter<T>
extends ForkJoinTask<T>A ForkJoinTask ,当触发时执行完成操作,并且没有剩余的待处理操作。 CountedCompleters通常比其他形式的ForkJoinTasks在子任务停顿和阻塞的情况下更加强大,但是不太直观的编程。 CountedCompleter的使用与其他基于完成的组件(例如CompletionHandler )的使用类似,但可能需要多个未完成的完成才能触发完成操作onCompletion(CountedCompleter) ,而不仅仅是一个。 除非另有初始化, pending count开始于零,但也可以是(原子),使用方法改变setPendingCount(int) , addToPendingCount(int)和compareAndSetPendingCount(int, int) 。 在调用tryComplete()时,如果待处理的行动计数不为零,则递减; 否则,执行完成操作,如果完成者本身具有完整性,则该过程将继续完成。 与相关同步组件(如Phaser和Semaphore)的情况一样 ,这些方法仅影响内部计数; 他们没有建立任何进一步的内部簿记。 特别地,未维护未决任务的身份。 如下所示,您可以创建在需要时记录一些或所有待处理任务或其结果的子类。 如下所示,还提供了支持定制完成遍历的实用程序方法。 然而,由于CountedCompleters仅提供基本的同步机制,因此创建进一步的抽象子类可能是有用的,这些子类保持适用于一组相关用法的链接,字段和其他支持方法。
具体的CountedCompleter类必须定义方法compute() ,在大多数情况下(如下所示),在tryComplete()之前调用tryComplete()一次。 该类还可以可选地覆盖方法onCompletion(CountedCompleter)以在正常完成时执行动作,并且方法onExceptionalCompletion(Throwable, CountedCompleter)对任何异常执行动作。
CountedCompleter通常不承担结果,在这种情况下,它们通常被声明为CountedCompleter<Void> ,并将始终返回null作为结果值。 在其他情况下,你应该重写方法getRawResult()提供从结果join(), invoke() ,以及相关方法。 一般来说,该方法应该返回在完成后保存结果的CountedCompleter对象的一个字段(或一个或多个字段的函数)的值。 默认方法setRawResult(T)在CountedCompleters中不起作用。 可能但很少适用于覆盖此方法来维护其他对象或保存结果数据的字段。
一个CountedCompleter本身不具有一个完整的(即getCompleter()返回null )可以用作这个添加的功能的常规ForkJoinTask。 然而,任何完成者又具有另一个完成者仅用作其他计算的内部帮助器,因此其自己的任务状态(如方法如ForkJoinTask.isDone()所报告)是任意的; 这种状况只有在明确调用改变complete(T) , ForkJoinTask.cancel(boolean) , ForkJoinTask.completeExceptionally(Throwable)或方法的特殊结束后compute 。 在任何异常完成之后,如果有任何异常可能会被传递到任务的完成者(以及其完成者等),如果存在并且尚未完成。 同样地,取消一个内部的CountedCompleter只对该完成者有局部的影响,所以并不常用。
示例用法
并行递归分解。 CountedCompleters可能被安排在与RecursiveAction经常使用的类似的树中,尽管与设置相关的结构通常有所不同。 这里,每个任务的完成者是其计算树中的父项。 即使它们需要更多的簿记,CountedCompleters可能是更好的选择,当应用可能耗时的操作(不能进一步细分)到数组或集合的每个元素; 特别是当操作对于一些元素的时间要比其他元素完成时要多得多,这是因为内在的变化(例如I / O)或诸如垃圾收集的辅助效应。 因为CountedCompleters提供自己的延续,其他线程不需要阻止等待执行它们。
例如,这是一个初始版本的类,它使用二分法递归分解将工作分成单个部分(叶子任务)。 即使将工作分解为单独的调用,基于树的技术通常比直接分支叶子任务更为可取,因为它们可以减少线程间通信并改善负载平衡。 在递归的情况下,要完成的每对子任务副本中的第二个触发器完成其父进程(因为没有执行结果组合,所以方法onCompletion的默认无操作实现不被覆盖)。 静态实用程序方法设置基本任务并调用它(这里隐含地使用ForkJoinPool.commonPool() )。
class MyOperation<E> { void apply(E e) { ... } } class ForEach<E> extends CountedCompleter<Void> { public static <E> void forEach(E[] array, MyOperation<E> op) { new ForEach<E>(null, array, op, 0, array.length).invoke(); } final E[] array; final MyOperation<E> op; final int lo, hi; ForEach(CountedCompleter<?> p, E[] array, MyOperation<E> op, int lo, int hi) { super(p); this.array = array; this.op = op; this.lo = lo; this.hi = hi; } public void compute() { // version 1 if (hi - lo >= 2) { int mid = (lo + hi) >>> 1; setPendingCount(2); // must set pending count before fork new ForEach(this, array, op, mid, hi).fork(); // right child new ForEach(this, array, op, lo, mid).fork(); // left child } else if (hi > lo) op.apply(array[lo]); tryComplete(); } } 通过注意到在递归的情况下,该任务在分配正确的任务后无关,因此可以在返回之前直接调用其左任务,从而可以改善此设计。 (这是一个尾递归删除的模拟。)另外,因为任务在执行其左任务时返回(而不是通过调用tryComplete ),待处理的计数设置为1:
class ForEach<E> ... public void compute() { // version 2 if (hi - lo >= 2) { int mid = (lo + hi) >>> 1; setPendingCount(1); // only one pending new ForEach(this, array, op, mid, hi).fork(); // right child new ForEach(this, array, op, lo, mid).compute(); // direct invoke } else { if (hi > lo) op.apply(array[lo]); tryComplete(); } } 作为一个进一步的改进,注意左边的任务甚至不存在。 而不是创建一个新的,我们可以迭代使用原始任务,并为每个fork添加一个挂起的计数。 另外,因为这个树中没有任务实现onCompletion(CountedCompleter)方法, tryComplete()可以替换为propagateCompletion() 。
class ForEach<E> ... public void compute() { // version 3 int l = lo, h = hi; while (h - l >= 2) { int mid = (l + h) >>> 1; addToPendingCount(1); new ForEach(this, array, op, mid, h).fork(); // right child h = mid; } if (h > l) op.apply(array[l]); propagateCompletion(); } 这些类的额外改进可能需要预先计算待处理的计数,以便它们可以在构造函数中建立,专门用于叶子步骤的类,按每个重复的四个细分,而不是两个细分,并使用自适应阈值,而不是总是细分为单个元素。
搜索。 CountedCompleters的树可以在数据结构的不同部分搜索一个值或属性,一旦发现结果,就会在AtomicReference中报告结果。 其他人可以轮询结果,以避免不必要的工作。 (您可以另外提供cancel其他任务,但通常只需让他们注意到结果被设置,并且如果是跳过进一步处理,则通常更简单和更有效)。再次使用完全分区(再次,在实践中,叶任务)几乎总是处理多个元素):
class Searcher<E> extends CountedCompleter<E> { final E[] array; final AtomicReference<E> result; final int lo, hi; Searcher(CountedCompleter<?> p, E[] array, AtomicReference<E> result, int lo, int hi) { super(p); this.array = array; this.result = result; this.lo = lo; this.hi = hi; } public E getRawResult() { return result.get(); } public void compute() { // similar to ForEach version 3 int l = lo, h = hi; while (result.get() == null && h >= l) { if (h - l >= 2) { int mid = (l + h) >>> 1; addToPendingCount(1); new Searcher(this, array, result, mid, h).fork(); h = mid; } else { E x = array[l]; if (matches(x) && result.compareAndSet(null, x)) quietlyCompleteRoot(); // root task is now joinable break; } } tryComplete(); // normally complete whether or not found } boolean matches(E e) { ... } // return true if found public static <E> E search(E[] array) { return new Searcher<E>(null, array, new AtomicReference<E>(), 0, array.length).invoke(); } } 在此示例中,以及其他任务除了compareAndSet设置常见结果之外没有其他效果,tryComplete的后续无条件tryComplete可以被设置为有条件的( if (result.get() == null) tryComplete(); ),因为一旦根任务完成,就不需要进一步的簿记管理完成。
记录子任务 结合多个子任务的CountedCompleter任务通常需要在方法onCompletion(CountedCompleter)中访问这些结果。 如下面的类所示(执行map-reduce的简化形式,其中映射和缩减都是类型为E ),分割和征服设计的一种方法是使每个子任务记录成为兄弟,以便它可以可以在方法onCompletion访问。 这种技术适用于结合左和右结果的顺序无关紧要的减少; 有序减少需要明确的左/右指定。 上述示例中可以看到其他流程图的变体。
class MyMapper<E> { E apply(E v) { ... } } class MyReducer<E> { E apply(E x, E y) { ... } } class MapReducer<E> extends CountedCompleter<E> { final E[] array; final MyMapper<E> mapper; final MyReducer<E> reducer; final int lo, hi; MapReducer<E> sibling; E result; MapReducer(CountedCompleter<?> p, E[] array, MyMapper<E> mapper, MyReducer<E> reducer, int lo, int hi) { super(p); this.array = array; this.mapper = mapper; this.reducer = reducer; this.lo = lo; this.hi = hi; } public void compute() { if (hi - lo >= 2) { int mid = (lo + hi) >>> 1; MapReducer<E> left = new MapReducer(this, array, mapper, reducer, lo, mid); MapReducer<E> right = new MapReducer(this, array, mapper, reducer, mid, hi); left.sibling = right; right.sibling = left; setPendingCount(1); // only right is pending right.fork(); left.compute(); // directly execute left } else { if (hi > lo) result = mapper.apply(array[lo]); tryComplete(); } } public void onCompletion(CountedCompleter<?> caller) { if (caller != this) { MapReducer<E> child = (MapReducer<E>)caller; MapReducer<E> sib = child.sibling; if (sib == null || sib.result == null) result = child.result; else result = reducer.apply(child.result, sib.result); } } public E getRawResult() { return result; } public static <E> E mapReduce(E[] array, MyMapper<E> mapper, MyReducer<E> reducer) { return new MapReducer<E>(null, array, mapper, reducer, 0, array.length).invoke(); } } 这里,方法onCompletion采用了结合结果的许多完成设计共同的形式。 这种回调式方法在每个任务中触发一次,在挂起计数的两个不同上下文中的任一个中,或者当任务本身调用时其挂起的计数为零时变为零:(1),或者tryComplete时的挂起计数为零,或(2)通过任何其子任务,当它们完成并将待处理的计数递减到零时。 caller论证区分案例。 通常,当呼叫方为this时,不需要采取任何行动。 否则,可以使用调用者参数(通常通过转换)来提供要组合的值(和/或链接到其他值)。 假设正确使用挂起计数,里面的动作onCompletion发生(一次)一个任务,其子任务完成时。 在此方法中不需要额外的同步来确保对此任务或其他完成任务的字段的访问的线程安全性。
完成遍历 。 如果使用onCompletion处理完成不适用或不方便,您可以使用方法firstComplete()和nextComplete()创建自定义遍历。 例如,要定义一个仅以第三个ForEach示例的形式分割右侧任务的MapReducer,完成必须按照未用尽的子任务链接合作减少,可以如下完成:
class MapReducer<E> extends CountedCompleter<E> { // version 2 final E[] array; final MyMapper<E> mapper; final MyReducer<E> reducer; final int lo, hi; MapReducer<E> forks, next; // record subtask forks in list E result; MapReducer(CountedCompleter<?> p, E[] array, MyMapper<E> mapper, MyReducer<E> reducer, int lo, int hi, MapReducer<E> next) { super(p); this.array = array; this.mapper = mapper; this.reducer = reducer; this.lo = lo; this.hi = hi; this.next = next; } public void compute() { int l = lo, h = hi; while (h - l >= 2) { int mid = (l + h) >>> 1; addToPendingCount(1); (forks = new MapReducer(this, array, mapper, reducer, mid, h, forks)).fork(); h = mid; } if (h > l) result = mapper.apply(array[l]); // process completions by reducing along and advancing subtask links for (CountedCompleter<?> c = firstComplete(); c != null; c = c.nextComplete()) { for (MapReducer t = (MapReducer)c, s = t.forks; s != null; s = t.forks = s.next) t.result = reducer.apply(t.result, s.result); } } public E getRawResult() { return result; } public static <E> E mapReduce(E[] array, MyMapper<E> mapper, MyReducer<E> reducer) { return new MapReducer<E>(null, array, mapper, reducer, 0, array.length, null).invoke(); } } 触发器 一些CountedCompleters本身从来没有分叉,而是作为其他设计中的一些管道; 包括完成一个或多个异步任务触发另一个异步任务。 例如:
class HeaderBuilder extends CountedCompleter<...> { ... } class BodyBuilder extends CountedCompleter<...> { ... } class PacketSender extends CountedCompleter<...> { PacketSender(...) { super(null, 1); ... } // trigger on second completion public void compute() { } // never called public void onCompletion(CountedCompleter<?> caller) { sendPacket(); } } // sample use: PacketSender p = new PacketSender(); new HeaderBuilder(p, ...).fork(); new BodyBuilder(p, ...).fork(); 从以下版本开始:
构造器:
Modifier | Constructor and Description |
protected | CountedCompleter() 创建一个新的CountedCompleter,没有完成,初始挂起计数为零。 |
protected | CountedCompleter(CountedCompleter<?> completer) 创建一个新的CountedCompleter与给定的完成者和初始挂起计数为零。 |
protected | CountedCompleter(CountedCompleter<?> completer, int initialPendingCount) 创建一个新的CountedCompleter与给定的完成和初始挂起计数。 |
核心方法:
Modifier and Type | Method and Description |
void | addToPendingCount(int delta) 将给定值添加(原子地)给挂起的计数。 |
boolean | compareAndSetPendingCount(int expected, int count) 只有当当前持有给定的预期值时,将挂起的计数设置为(原子地)给定计数。 |
void | complete(T rawResult) 不管挂起计数,调用 onCompletion(CountedCompleter) ,将此任务标记为完成,并进一步触发 tryComplete()对此任务的完成(如果存在)。 |
abstract void | compute() 这个任务执行的主要计算。 |
int | decrementPendingCountUnlessZero() 如果挂起的计数非零,(原子地)减少它。 |
protected boolean | exec() 实现CountedCompleters的执行约定。 |
CountedCompleter<?> | firstComplete() 如果此任务的挂起计数为零,则返回此任务; 否则递减其挂起的计数并返回null 。 |
CountedCompleter<?> | getCompleter() 返回成立于这项任务的构造函数中完成者,或 null如果没有。 |
int | getPendingCount() 返回当前挂起的计数。 |
T | getRawResult() 返回计算结果。 |
CountedCompleter<?> | getRoot() 返回当前计算的根; 即这个任务,如果它没有完成,否则它的完成者的根。 |
void | helpComplete(int maxTasks) 如果此任务尚未完成,则尝试至少处理此任务在完成路径上的给定数量的其他未处理任务(如果有)。 |
CountedCompleter<?> | nextComplete() 如果此任务没有完成,请调用 ForkJoinTask.quietlyComplete()并返回 null 。 |
void | onCompletion(CountedCompleter<?> caller) 当方法 tryComplete()被调用并且挂起的计数为零时,或者当调用无条件方法 complete(T)时,执行一个动作。 |
boolean | onExceptionalCompletion(Throwable ex, CountedCompleter<?> caller) 方法 ForkJoinTask.completeExceptionally(Throwable)被调用或方法 compute()引发异常,并且此任务尚未正常完成时执行操作。 |
void | propagateCompletion() 相当于tryComplete()但并不在完成路径中调用onCompletion(CountedCompleter) :如果挂起的计数为非零,则递减计数; 否则,同样尝试完成此任务的完成,如果存在,否则将此任务标记为完成。 |
void | quietlyCompleteRoot() 相当于 getRoot().quietlyComplete() 。 |
void | setPendingCount(int count) 将待处理计数设置为给定值。 |
protected void | setRawResult(T t) 带有CountedCompleters结果的方法可以可选地用于帮助维护结果数据。 |
void | tryComplete() 如果挂起的计数不为零,则减去计数; 否则调用onCompletion(CountedCompleter) ,然后类似地尝试完成此任务的完成,如果存在,否则将此任务标记为完成。 |
32、DoubleAdder
public class DoubleAdder
extends Number
implements Serializable一个或多个变量一起保持初始为零double总和。 当跨线程争用更新(方法add(double) )时,该变量集可以动态增长以减少争用。 方法sum() (或等价于doubleValue() )返回保持总和的整个变量组合的当前总和。 线程内或跨线程的累积顺序不能保证。 因此,如果需要数值稳定性,特别是当组合几乎不同数量级的值时,该类可能不适用。
当多个线程更新用于诸如经常更新但较不频繁读取的摘要统计信息的常用值时,此类通常优于替代方案。
该类扩展Number ,但不定义诸如方法equals , hashCode和compareTo ,因为实例预计将发生突变,所以不如收集钥匙有用。
构造器:
Constructor and Description |
DoubleAdder() 创建一个新的加法器,初始和为零。 |
核心方法:
Modifier and Type | Method and Description |
void | add(double x) 添加给定值。 |
double | doubleValue() 相当于 sum() 。 |
float | floatValue() 在 缩小原始 float后返回 sum()作为float。 |
int | intValue() 在 缩小原始 int后,返回 sum()作为int。 |
long | longValue() 在 缩小原始 long后返回 sum()作为long。 |
void | reset() 将保持总和的变量重置为零。 |
double | sum() 返回当前总和。 |
double | sumThenReset() 等效于 sum()后跟 reset() 。 |
String | toString() 返回 sum()的String表示 形式 。 |
33、DoubleAccumulator
public class DoubleAccumulator
extends Number
implements Serializable一个或多个变量,它们一起保持运行double使用所提供的功能更新值。 当更新(方法accumulate(double) )跨线程竞争时,变量集可以动态增长以减少争用。 方法get() (或等效地, doubleValue() )返回维护更新的变量的当前值。
当多个线程更新用于诸如经常更新但较不频繁读取的摘要统计信息的常用值时,此类通常优于替代方案。
提供的累加器功能应该是无效的,因为尝试的更新由于线程之间的争用而失败时可能会被重新应用。 该函数应用当前值作为其第一个参数,给定的更新作为第二个参数。 例如,为了保持最大值的运行,您可以提供Double::max以及Double.NEGATIVE_INFINITY作为身份。 线程内或跨线程的累积顺序不能保证。 因此,如果需要数值稳定性,特别是当组合几乎不同数量级的值时,该类可能不适用。
类别DoubleAdder提供了类的功能的这个类的常见的特殊情况下维持和。 电话new DoubleAdder()相当于new DoubleAccumulator((x, y) -> x + y, 0.0) 。
该类扩展Number ,但不定义诸如方法equals , hashCode和compareTo ,因为实例预计将发生突变,所以不如收集钥匙有用。
构造器:
Constructor and Description |
DoubleAccumulator(DoubleBinaryOperator accumulatorFunction, double identity) 使用给定的累加器函数和identity元素创建一个新的实例。 |
核心方法:
Modifier and Type | Method and Description |
void | accumulate(double x) 具有给定值的更新。 |
double | doubleValue() 相当于 get() 。 |
float | floatValue() 在 缩小原始 float后返回 current value作为float。 |
double | get() 返回当前值。 |
double | getThenReset() 相当于将 get()其次是 reset() 。 |
int | intValue() 在 缩小原始 int后返回 current value作为int。 |
long | longValue() 在 缩小原始 long后返回 current value作为long。 |
void | reset() 重置维持更新到标识值的变量。 |
String | toString() 返回当前值的String表示形式。 |
34、Executors.newWorkStealingPool
Java8的第五种线程池创建方法,具体如下:
newWorkStealingPool()
创建使用所有 available processors作为其目标并行级别的工作窃取线程池。
public static ExecutorService newWorkStealingPool()使用所有 available processors作为其目标并行级别创建一个工作窃取线程池。
结果
新创建的线程池
newWorkStealingPool(int parallelism)
创建一个维护足够的线程以支持给定的并行级别的线程池,并且可以使用多个队列来减少争用。
public static ExecutorService newWorkStealingPool(int parallelism)创建一个维护足够的线程以支持给定的并行级别的线程池,并且可以使用多个队列来减少争用。 并行级别对应于主动参与或可以从事任务处理的最大线程数。 线程的实际数量可以动态增长和收缩。 工作窃取池不保证执行提交的任务的顺序。
参数
parallelism - 目标平行度水平
结果
新创建的线程池
异常
IllegalArgumentException - 如果是 parallelism <= 0
35、ForkJoinPool.commonPool
commonPool()
返回公共池实例。
public static ForkJoinPool commonPool()返回公共池实例。 这个游泳池是静态的; 其运行状态不受尝试shutdown()或shutdownNow()的影响 。 但是,该池和任何正在进行的处理将在程序System.exit(int)自动终止 。 在程序终止前依赖于异步任务处理完成的任何程序,应在退出之前调用commonPool(). awaitQuiescence 。
结果
公共池实例
36、ForkJoinPool.getCommonPoolParallelism
getCommonPoolParallelism()
返回公共池的目标并行度级别。
public static int getCommonPoolParallelism()返回公共池的目标并行度级别。
结果
共同池的目标平行度水平
37、LongAdder
public class LongAdder
extends Number
implements Serializable一个或多个变量一起维持初始为零long总和。 当更新(方法add(long) )跨线程竞争时,变量集可以动态增长以减少争用。 方法sum() (或等效地, longValue() )返回保持总和的整个变量组合的当前总和。
这个类是通常优选AtomicLong当多个线程更新时使用,用于诸如收集统计信息,不用于细粒度同步控制的共同总和。 在低更新争议下,这两类具有相似的特征。 但是,在高度争议的情况下,这一类的预期吞吐量明显高于牺牲更高的空间消耗。
LongAdders可以使用ConcurrentHashMap来维护可扩展的频率映射(一种直方图或多集)。 例如,要向ConcurrentHashMap<String,LongAdder> freqs添加一个计数,如果尚未存在,则可以使用freqs.computeIfAbsent(k -> new LongAdder()).increment();
该类扩展Number ,但不定义诸如方法equals , hashCode和compareTo ,因为实例预计将发生突变,所以不如收集钥匙有用。
构造器:
Constructor and Description |
LongAdder() 创建一个新的加法器,初始和为零。 |
核心方法:
Modifier and Type | Method and Description |
void | add(long x) 添加给定值。 |
void | decrement() 相当于 add(-1) 。 |
double | doubleValue() 返回 sum()为 double一个宽元转换后。 |
float | floatValue() 返回 sum()为 float一个宽元转换后。 |
void | increment() 相当于 add(1) 。 |
int | intValue() 在 缩小原始 int后返回 sum()作为int。 |
long | longValue() 相当于 sum() 。 |
void | reset() 将保持总和的变量重置为零。 |
long | sum() 返回当前总和。 |
long | sumThenReset() 相当于 sum()后跟 reset() 。 |
String | toString() 返回 sum()的String表示 形式 。 |
38、LongAccumulator
public class LongAccumulator
extends Number
implements Serializable一个或多个变量一起保持使用提供的功能更新的运行的值long 。 当跨线程争用更新(方法accumulate(long) )时,该变量集可以动态增长以减少争用。 方法get() (或等价于longValue() )返回维护更新的变量的当前值。
当多线程更新用于收集统计信息的公共值时,此类通常优于AtomicLong,而不是细粒度的同步控制。 在低更新争议下,这两类具有相似的特征。 但是,在高度争议的情况下,这一类的预期吞吐量明显高于牺牲更高的空间消耗。
线程内或跨线程的累积顺序不能得到保证,不能依赖,所以此类仅适用于积累顺序无关的功能。 提供的累加器功能应该是无效的,因为尝试的更新由于线程之间的争用而失败时可能会被重新应用。 该函数应用当前值作为其第一个参数,给定的更新作为第二个参数。 例如,为了保持最大值,您可以提供Long::max以及Long.MIN_VALUE作为身份。
LongAdder课程提供了类别功能的类别,用于维护计数和总和的常见特殊情况。 电话new LongAdder()相当于new LongAccumulator((x, y) -> x + y, 0L 。
该类扩展Number ,但不定义诸如方法equals , hashCode和compareTo ,因为实例预计将发生突变,所以不如收集钥匙有用。
构造器:
Constructor and Description |
LongAccumulator(LongBinaryOperator accumulatorFunction, long identity) 使用给定的累加器函数和identity元素创建一个新的实例。 |
核心方法:
Modifier and Type | Method and Description |
void | accumulate(long x) 具有给定值的更新。 |
double | doubleValue() 返回 current value为 double一个宽元转换后。 |
float | floatValue() 返回 current value为 float一个宽元转换后。 |
long | get() 返回当前值。 |
long | getThenReset() 相当于 get()其次是 reset() 。 |
int | intValue() 在 缩小原始 int后返回 current value作为int。 |
long | longValue() 相当于 get() 。 |
void | reset() 重置维持更新到标识值的变量。 |
String | toString() 返回当前值的String表示形式。 |
39、StampedLock
public class StampedLock
extends Object
implements Serializable一种基于能力的锁,具有三种模式用于控制读/写访问。 StampedLock的状态由版本和模式组成。 锁定采集方法返回一个表示和控制相对于锁定状态的访问的印记; 这些方法的“尝试”版本可能会返回特殊值为零以表示获取访问失败。 锁定释放和转换方法要求邮票作为参数,如果它们与锁的状态不匹配则失败。 这三种模式是:
写作。 方法writeLock()可能阻止等待独占访问,返回可以在方法unlockWrite(long)中使用的邮票来释放锁定。 不定时的和定时版本tryWriteLock ,还提供。 当锁保持写入模式时,不能获得读取锁定,并且所有乐观读取验证都将失败。
读。 方法readLock()可能阻止等待非独占访问,返回可用于方法unlockRead(long)释放锁的戳记 。 不定时的和定时版本tryReadLock ,还提供。
乐观阅读 方法tryOptimisticRead()只有当锁当前未保持在写入模式时才返回非零标记。 方法validate(long)返回true,如果在获取给定的邮票时尚未在写入模式中获取锁定。 这种模式可以被认为是一个非常弱的版本的读锁,可以随时由作家打破。 对简单的只读代码段使用乐观模式通常会减少争用并提高吞吐量。 然而,其使用本质上是脆弱的。 乐观阅读部分只能读取字段并将其保存在局部变量中,以供后验证使用。 以乐观模式读取的字段可能会非常不一致,因此只有在熟悉数据表示以检查一致性和/或重复调用方法validate()时,使用情况才适用。 例如,当首次读取对象或数组引用,然后访问其字段,元素或方法之一时,通常需要这样的步骤。
此类还支持有条件地在三种模式下提供转换的方法。 例如,方法tryConvertToWriteLock(long)尝试“升级”模式,如果(1)在读取模式下已经在写入模式(2)中并且没有其他读取器或(3)处于乐观模式并且锁可用,则返回有效写入戳记。 这些方法的形式旨在帮助减少在基于重试的设计中出现的一些代码膨胀。
StampedLocks设计用作线程安全组件开发中的内部实用程序。 他们的使用依赖于他们保护的数据,对象和方法的内部属性的知识。 它们不是可重入的,所以锁定的机构不应该调用其他可能尝试重新获取锁的未知方法(尽管您可以将戳记传递给可以使用或转换它的其他方法)。 读锁定模式的使用依赖于相关的代码段是无副作用的。 未经验证的乐观阅读部分不能调用不知道容忍潜在不一致的方法。 邮票使用有限表示,并且不是加密安全的(即,有效的邮票可能是可猜测的)。 邮票值可以在连续运行一年后(不早于)回收。 不超过此期限使用或验证的邮票可能无法正确验证。 StampedLocks是可序列化的,但总是反序列化为初始解锁状态,因此它们对于远程锁定无用。
StampedLock的调度策略不一致优先于读者,反之亦然。 所有“尝试”方法都是尽力而为,并不一定符合任何调度或公平政策。 用于获取或转换锁定的任何“try”方法的零返回不携带关于锁的状态的任何信息; 随后的调用可能会成功。
因为它支持跨多个锁模式的协调使用,所以该类不直接实现Lock或ReadWriteLock接口。 然而,StampedLock可以看作asReadLock() , asWriteLock() ,或asReadWriteLock()中,仅需要在一组相关联的功能的应用程序。
样品用法。 下面说明了一个维护简单二维点的类中的一些使用习语。 示例代码说明了一些try / catch约定,即使这些惯例在这里不是严格需要的,因为它们的身体中不会发生异常。
class Point { private double x, y; private final StampedLock sl = new StampedLock(); void move(double deltaX, double deltaY) { // an exclusively locked method long stamp = sl.writeLock(); try { x += deltaX; y += deltaY; } finally { sl.unlockWrite(stamp); } } double distanceFromOrigin() { // A read-only method long stamp = sl.tryOptimisticRead(); double currentX = x, currentY = y; if (!sl.validate(stamp)) { stamp = sl.readLock(); try { currentX = x; currentY = y; } finally { sl.unlockRead(stamp); } } return Math.sqrt(currentX * currentX + currentY * currentY); } void moveIfAtOrigin(double newX, double newY) { // upgrade // Could instead start with optimistic, not read mode long stamp = sl.readLock(); try { while (x == 0.0 && y == 0.0) { long ws = sl.tryConvertToWriteLock(stamp); if (ws != 0L) { stamp = ws; x = newX; y = newY; break; } else { sl.unlockRead(stamp); stamp = sl.writeLock(); } } } finally { sl.unlock(stamp); } } }
构造器:
Constructor and Description |
StampedLock() 创建一个新的锁,最初处于未锁定状态。 |
核心方法:
Modifier and Type | Method and Description |
Lock | asReadLock() 返回此StampedLock的一个简单的Lock视图,其中Lock.lock()方法映射到readLock() ,并且类似地用于其他方法。 |
ReadWriteLock | asReadWriteLock() 返回此StampedLock的ReadWriteLock视图,其中ReadWriteLock.readLock()方法映射到asReadLock(),ReadWriteLock.writeLock() 转换为asWriteLock() 。 |
Lock | asWriteLock() 返回此StampedLock的一个简单的Lock视图,其中Lock.lock()方法映射到writeLock() ,并且类似地用于其他方法。 |
int | getReadLockCount() 查询为此锁持有的读取锁的数量。 |
boolean | isReadLocked() 返回 true如果锁当前是非排他地。 |
boolean | isWriteLocked() 返回 true如果锁当前是唯一的。 |
long | readLock() 不排他地获取锁定,如有必要,阻塞。 |
long | readLockInterruptibly() 非排他性地获取锁定,如有必要,阻塞,直到可用或当前线程中断。 |
String | toString() 返回一个标识此锁的字符串以及其锁定状态。 |
long | tryConvertToOptimisticRead(long stamp) 如果锁定状态符合给定的印记,则如果印记表示持有锁定,则释放它并返回观察印记。 |
long | tryConvertToReadLock(long stamp) 如果锁定状态与给定的标记匹配,则执行以下操作之一。 |
long | tryConvertToWriteLock(long stamp) 如果锁定状态与给定的标记匹配,则执行以下操作之一。 |
long | tryOptimisticRead() 返回可以稍后验证的印记,如果专门锁定则返回零。 |
long | tryReadLock() 非专门获取锁,如果它立即可用。 |
long | tryReadLock(long time, TimeUnit unit) 如果在给定时间内可用,并且当前线程未被中断,则非排他性地获取锁。 |
boolean | tryUnlockRead() 释放读锁定的一个保持位,如果保持,而不需要戳记值。 |
boolean | tryUnlockWrite() 释放写入锁定,如果被保留,而不需要标记值。 |
long | tryWriteLock() 专门获取锁,如果它立即可用。 |
long | tryWriteLock(long time, TimeUnit unit) 如果在给定时间内可用,并且当前线程未被中断,则专门获取该锁。 |
void | unlock(long stamp) 如果锁定状态与给定的标记匹配,则释放相应的锁定模式。 |
void | unlockRead(long stamp) 如果锁定状态与给定的标记匹配,则释放非排他锁。 |
void | unlockWrite(long stamp) 如果锁定状态与给定的邮票相匹配,则释放排他锁。 |
boolean | validate(long stamp) 如果从发布给定邮票以来没有专门获取锁,则返回true。 |
long | writeLock() 专门获取锁定,如有必要,阻塞。 |
long | writeLockInterruptibly() 专门获取锁定,如有必要,阻塞,直到可用或当前线程中断。 |