diff --git a/README.md b/README.md index 50e5e1c6..e14b9893 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ - 当然基本的并发关注方面及其复杂性,与具体使用哪个工具无关,都是要理解与注意的 - **高层抽象** - 或说 以业务流程的形式表达技术的并发流程 - - 可以不使用繁琐易错的基础并发协调工具,如[`CountDownLatch`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/CountDownLatch.html)、锁([`Lock`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/locks/package-summary.html))、信号量([`Semaphore`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html)) + - 可以不使用繁琐易错的基础并发协调工具,如锁([`Lock`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/locks/package-summary.html))、[`CountDownLatch`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/CountDownLatch.html)、信号量([`Semaphore`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html))、[`CyclicBarrier`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/CyclicBarrier.html) 和其它并发工具、框架一样,`CompletableFuture`用于 @@ -182,6 +182,7 @@ public class CffuDemo { final Cffu combined = longTaskA.thenCombine(longTaskB, Integer::sum) .orTimeout(1500, TimeUnit.MILLISECONDS); System.out.println("combined result: " + combined.get()); + final Cffu anyOfSuccess = cffuFactory.anyOfSuccess(longTaskC, longFailedTask); System.out.println("anyOfSuccess result: " + anyOfSuccess.get()); } @@ -219,9 +220,11 @@ public class CompletableFutureUtilsDemo { }, myBizThreadPool); final CompletableFuture combined = longTaskA.thenCombine(longTaskB, Integer::sum); - final CompletableFuture combinedWithTimeout = CompletableFutureUtils.orTimeout(combined, 1500, TimeUnit.MILLISECONDS); + final CompletableFuture combinedWithTimeout = + CompletableFutureUtils.orTimeout(combined, 1500, TimeUnit.MILLISECONDS); System.out.println("combined result: " + combinedWithTimeout.get()); - final CompletableFuture anyOfSuccess = CompletableFutureUtils.anyOfSuccessWithType(longTaskC, longFailedTask); + + final CompletableFuture anyOfSuccess = CompletableFutureUtils.anyOfSuccess(longTaskC, longFailedTask); System.out.println("anyOfSuccess result: " + anyOfSuccess.get()); } } @@ -263,6 +266,7 @@ fun main() { val combined = longTaskA.thenCombine(longTaskB, Integer::sum) .orTimeout(1500, TimeUnit.MILLISECONDS) println("combined result: ${combined.get()}") + val anyOfSuccess: Cffu = listOf(longTaskC, longFailedTask).anyOfSuccessCffu() println("anyOfSuccess result: ${anyOfSuccess.get()}") } @@ -282,19 +286,20 @@ fun main() { 示例代码如下: ```java -public class AllOfWithResultDemo { +public class AllResultsOfDemo { public static final Executor myBizExecutor = Executors.newCachedThreadPool(); public static final CffuFactory cffuFactory = newCffuFactoryBuilder(myBizExecutor).build(); - public static void main(String[] args) { + public static void main(String[] args) throws Exception { ////////////////////////////////////////////////// - // CffuFactory#allOf + // CffuFactory#allResultsOf ////////////////////////////////////////////////// Cffu cffu1 = cffuFactory.completedFuture(21); Cffu cffu2 = cffuFactory.completedFuture(42); - Cffu allOf2 = cffuFactory.allOf(cffu1, cffu2); - // Result type is Void!! + Cffu allOf = cffuFactory.allOf(cffu1, cffu2); + // Result type is Void! + // // the result can be got by input argument `cf1.get()`, but it's cumbersome. // so we can see a lot the util methods to enhance allOf with result in our project. @@ -307,16 +312,16 @@ public class AllOfWithResultDemo { CompletableFuture cf1 = CompletableFuture.completedFuture(21); CompletableFuture cf2 = CompletableFuture.completedFuture(42); - CompletableFuture allOf = CompletableFuture.allOf(cf1, cf2); - // Result type is Void!! + CompletableFuture allOf2 = CompletableFuture.allOf(cf1, cf2); + // Result type is Void! - CompletableFuture> allResults2 = CompletableFutureUtils.allOfWithResult(cf1, cf2); + CompletableFuture> allResults2 = CompletableFutureUtils.allResultsOf(cf1, cf2); System.out.println(allResults2.get()); } } ``` -> \# 完整可运行的Demo代码参见[`AllOfWithResultDemo.java`](cffu-core/src/test/java/io/foldright/demo/AllOfWithResultDemo.java)。 +> \# 完整可运行的Demo代码参见[`AllResultsOfDemo.java`](cffu-core/src/test/java/io/foldright/demo/AllResultsOfDemo.java)。 上面多个相同结果类型的`CF`,`cffu`还提供了返回多个不同类型`CF`结果的方法,`cffuCombine`/`CompletableFutureUtils#combine`方法。 @@ -334,9 +339,9 @@ public class CffuCombineDemo { Cffu cffu1 = cffuFactory.completedFuture("21"); Cffu cffu2 = cffuFactory.completedFuture(42); - Cffu> allOfWithResult = cffu1.cffuCombine(cffu2); + Cffu> combined = cffu1.cffuCombine(cffu2); // or: cffuFactory.cffuCombine(cffu1, cffu2); - System.out.println(allOfWithResult.get()); + System.out.println(combined.get()); ////////////////////////////////////////////////// // or CompletableFutureUtils.combine @@ -344,8 +349,8 @@ public class CffuCombineDemo { CompletableFuture cf1 = CompletableFuture.completedFuture("21"); CompletableFuture cf2 = CompletableFuture.completedFuture(42); - CompletableFuture> allOfWithResult2 = CompletableFutureUtils.combine(cf1, cf2); - System.out.println(allOfWithResult2.get()); + CompletableFuture> combined2 = CompletableFutureUtils.combine(cf1, cf2); + System.out.println(combined2.get()); } } ``` @@ -367,18 +372,19 @@ public class NoDefaultExecutorSettingForCompletableFuture { public static final Executor myBizExecutor = Executors.newCachedThreadPool(); public static void main(String[] args) { - CompletableFuture cf1 = CompletableFuture.runAsync(() -> System.out.println("doing a long time work!"), + CompletableFuture cf1 = CompletableFuture.runAsync( + () -> System.out.println("doing a long time work!"), myBizExecutor); CompletableFuture cf2 = CompletableFuture .supplyAsync( () -> { - System.out.println("doing another long time work!!"); + System.out.println("doing another long time work!"); return 42; }, myBizExecutor) .thenAcceptAsync( - i -> System.out.println("doing third long time work!!!"), + i -> System.out.println("doing third long time work!"), myBizExecutor); CompletableFuture.allOf(cf1, cf2).join(); @@ -399,9 +405,9 @@ public class DefaultExecutorSettingForCffu { Cffu cf1 = cffuFactory.runAsync(() -> System.out.println("doing a long time work!")); Cffu cf2 = cffuFactory.supplyAsync(() -> { - System.out.println("doing another long time work!!"); + System.out.println("doing another long time work!"); return 42; - }).thenAcceptAsync(i -> System.out.println("doing third long time work!!!")); + }).thenAcceptAsync(i -> System.out.println("doing third long time work!")); cffuFactory.allOf(cf1, cf2).join(); } @@ -414,7 +420,7 @@ public class DefaultExecutorSettingForCffu { - `CompletableFuture`的`allOf`方法会等待所有输入`CF`运行完成;即使有`CF`失败了也要等待后续`CF`运行完成,再返回一个失败的`CF`。 - 对于业务逻辑来说,这样失败且继续等待策略,减慢了业务响应性;会希望如果有输入`CF`失败了,则快速失败不再做于事无补的等待 - - `cffu`提供了相应的`allResultsOfFastFail`/`allOfFastFail`方法 + - `cffu`提供了相应的`allOfFastFail`/`allResultsOfFastFail`方法 - `allOf`/`allOfFastFail`两者都是,只有当所有的输入`CF`都成功时,才返回成功结果 - `CompletableFuture`的`anyOf`方法返回首个完成的`CF`(不会等待后续没有完成的`CF`,赛马模式);即使首个完成的`CF`是失败的,也会返回这个失败的`CF`结果。 - 对于业务逻辑来说,会希望赛马模式返回首个成功的`CF`结果,而不是首个完成但失败的`CF` @@ -443,7 +449,7 @@ public class ConcurrencyStrategyDemo { public static void main(String[] args) throws Exception { //////////////////////////////////////////////////////////////////////// - // CffuFactory#allResultsOfFastFail / allOfFastFail + // CffuFactory#allOfFastFail / allResultsOfFastFail // CffuFactory#anyOfSuccess //////////////////////////////////////////////////////////////////////// final Cffu successAfterLongTime = cffuFactory.supplyAsync(() -> { @@ -454,19 +460,17 @@ public class ConcurrencyStrategyDemo { // Result type is Void! Cffu cffuAll = cffuFactory.allOfFastFail(successAfterLongTime, failed); + Cffu> fastFailed = cffuFactory.allResultsOfFastFail(successAfterLongTime, failed); // fast failed without waiting successAfterLongTime System.out.println(fastFailed.exceptionNow()); - // Result type is Object! - Cffu cffuAny = cffuFactory.anyOfSuccess(successAfterLongTime, failed); - System.out.println(cffuAny.get()); Cffu anyOfSuccess = cffuFactory.anyOfSuccess(successAfterLongTime, failed); System.out.println(anyOfSuccess.get()); //////////////////////////////////////////////////////////////////////// - // or CompletableFutureUtils#allOfFastFailWithResult / allOfFastFail - // CompletableFutureUtils#anyOfSuccessWithType / anyOfSuccess + // or CompletableFutureUtils#allOfFastFail / allResultsOfFastFail + // CompletableFutureUtils#anyOfSuccess //////////////////////////////////////////////////////////////////////// final CompletableFuture successAfterLongTimeCf = CompletableFuture.supplyAsync(() -> { sleep(3000); // sleep LONG time @@ -476,14 +480,12 @@ public class ConcurrencyStrategyDemo { // Result type is Void! CompletableFuture cfAll = CompletableFutureUtils.allOfFastFail(successAfterLongTimeCf, failedCf); - CompletableFuture> fastFailedCf = CompletableFutureUtils.allOfFastFailWithResult(successAfterLongTimeCf, failedCf); + + CompletableFuture> fastFailedCf = CompletableFutureUtils.allResultsOfFastFail(successAfterLongTimeCf, failedCf); // fast failed without waiting successAfterLongTime System.out.println(CompletableFutureUtils.exceptionNow(fastFailedCf)); - // Result type is Object! - CompletableFuture cfAny = CompletableFutureUtils.anyOfSuccess(successAfterLongTimeCf, failedCf); - System.out.println(cfAny.get()); - CompletableFuture cfSuccess = CompletableFutureUtils.anyOfSuccessWithType(successAfterLongTimeCf, failedCf); + CompletableFuture cfSuccess = CompletableFutureUtils.anyOfSuccess(successAfterLongTimeCf, failedCf); System.out.println(cfSuccess.get()); } } diff --git a/cffu-core/src/main/java/io/foldright/cffu/Cffu.java b/cffu-core/src/main/java/io/foldright/cffu/Cffu.java index 795adfd1..81d440a6 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/Cffu.java +++ b/cffu-core/src/main/java/io/foldright/cffu/Cffu.java @@ -1330,7 +1330,7 @@ public T join() { * Waits if necessary for at most the given time for the computation to complete, * and then retrieves its result value when complete, or throws an (unchecked) exception if completed exceptionally. *

- * NOTE:
+ * NOTE:
* call this method *

* {@code result = cffu.join(timeout, unit);} @@ -1342,7 +1342,7 @@ public T join() { * .join(); * } * - * CAUTION:
+ * CAUTION:
* if the wait timed out, this method throws an (unchecked) {@link CompletionException} * with the {@link TimeoutException} as its cause; * NOT throws a (checked) {@link TimeoutException} like {@link #get(long, TimeUnit)}. @@ -1482,7 +1482,7 @@ public boolean isCancelled() { * Returns the computation state, this method just invoke without java version compatibility logic, * if you need this function backport into old {@code java 18-}, use {@link #cffuState()} instead. *

- * NOTE:
+ * NOTE:
* {@link CompletableFuture#state} is new method since Java 19, * this method should have compatibility logic for old Java version; * But the return type {@link Future.State} is also added since Java 19, @@ -1610,7 +1610,7 @@ public boolean cancel(boolean mayInterruptIfRunning) { * If this CompletableFuture completes exceptionally, then the returned CompletionStage completes * exceptionally with a CompletionException with this exception as cause. *

- * CAUTION:
+ * CAUTION:
* if run on old Java 8, just return a Cffu with * a *normal* underlying CompletableFuture which is NOT with a *minimal* CompletionStage. *

@@ -1839,11 +1839,11 @@ public void obtrudeException(Throwable ex) { * Subclasses of CompletableFuture should normally override this method to return an instance of the same class * as this CompletableFuture. The default implementation returns an instance of class CompletableFuture. *

- * NOTE:
+ * NOTE:
* this method existed mainly for API compatibility to {@code CompletableFuture}, * prefer {@link CffuFactory#newIncompleteCffu()}. *

- * CAUTION:
+ * CAUTION:
* for minimal stage instance({@link #isMinimalStage()}), if run on old Java 8, * just return a Cffu with a *normal* underlying CompletableFuture which is NOT with a *minimal* CompletionStage. * diff --git a/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java b/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java index d7050fee..5f2f71cd 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java @@ -92,7 +92,7 @@ public Cffu completedFuture(@Nullable T value) { * Returns a new CompletionStage that is already completed with the given value * and supports only those methods in interface {@link CompletionStage}. *

- * CAUTION:
+ * CAUTION:
* if run on old Java 8, just return a Cffu with * a *normal* underlying CompletableFuture which is NOT with a *minimal* CompletionStage. * @@ -124,7 +124,7 @@ public Cffu failedFuture(Throwable ex) { * Returns a new CompletionStage that is already completed exceptionally * with the given exception and supports only those methods in interface {@link CompletionStage}. *

- * CAUTION:
+ * CAUTION:
* if run on old Java 8, just return a Cffu with * a *normal* underlying CompletableFuture which is NOT with a *minimal* CompletionStage. * @@ -247,7 +247,7 @@ public Cffu newIncompleteCffu() { * for {@link CompletableFuture} class instances, * {@link Cffu#cffuUnwrap()} is the inverse operation to this method. *

- * NOTE, keep input stage unchanged if possible when wrap:
+ * NOTE, keep input stage unchanged if possible when wrap:
*

    *
  1. if input stage is a {@link Cffu}, re-wrapped with the config of * this {@link CffuFactory} from {@link CffuFactoryBuilder} by {@link Cffu#resetCffuFactory(CffuFactory)}. diff --git a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java index e93701bf..aa5f3123 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java @@ -21,7 +21,7 @@ /** - * This class contains the enhanced methods for {@link CompletableFuture}. + * This class contains the enhanced and backport methods for {@link CompletableFuture}. * * @author Jerry Lee (oldratlee at gmail dot com) */ @@ -462,8 +462,8 @@ public static CompletableFuture> } //////////////////////////////////////////////////////////////////////////////// - //# Backport CF methods - // compatibility for low Java version + //# Backport CF static methods + // compatibility for low Java versions //////////////////////////////////////////////////////////////////////////////// //# Factory methods @@ -489,7 +489,7 @@ public static CompletableFuture failedFuture(Throwable ex) { * Returns a new CompletionStage that is already completed with the given value * and supports only those methods in interface {@link CompletionStage}. *

    - * CAUTION:
    + * CAUTION:
    * if run on old Java 8, just return a *normal* CompletableFuture which is NOT with a *minimal* CompletionStage. * * @param value the value @@ -508,7 +508,7 @@ public static CompletionStage completedStage(@Nullable T value) { * Returns a new CompletionStage that is already completed exceptionally with * the given exception and supports only those methods in interface {@link CompletionStage}. *

    - * CAUTION:
    + * CAUTION:
    * if run on old Java 8, just return a *normal* CompletableFuture which is NOT with a *minimal* CompletionStage. * * @param ex the exception @@ -562,7 +562,7 @@ public static Executor delayedExecutor(long delay, TimeUnit unit, Executor execu } //////////////////////////////////////// - //# backport instance methods + //# Backport CF instance methods //////////////////////////////////////// //# Error Handling methods of CompletionStage @@ -718,7 +718,7 @@ public static CompletableFuture exceptionallyComposeAsync( * Waits if necessary for at most the given time for the computation to complete, * and then retrieves its result value when complete, or throws an (unchecked) exception if completed exceptionally. *

    - * NOTE:
    + * NOTE:
    * call this method *

    * {@code result = CompletableFutureUtils.join(cf, timeout, unit);} @@ -730,7 +730,7 @@ public static CompletableFuture exceptionallyComposeAsync( * .join(); * } * - * CAUTION:
    + * CAUTION:
    * if the wait timed out, this method throws an (unchecked) {@link CompletionException} * with the {@link TimeoutException} as its cause; * NOT throws a (checked) {@link TimeoutException} like {@link CompletableFuture#get(long, TimeUnit)}. @@ -913,7 +913,7 @@ public static CompletableFuture completeAsync( * If given CompletableFuture completes exceptionally, then the returned CompletionStage completes exceptionally * with a CompletionException with given exception as cause. *

    - * CAUTION:
    + * CAUTION:
    * if run on old Java 8, just return a *normal* CompletableFuture which is NOT with a *minimal* CompletionStage. * * @return the new CompletionStage @@ -963,7 +963,7 @@ public static CompletableFuture newIncompleteFuture(CompletableFuture< * Returns the default Executor used for async methods that do not specify an Executor. * This class uses the {@link ForkJoinPool#commonPool()} if it supports more than one parallel thread, * or else an Executor using one thread per async task.
    - * CAUTION:This executor may be not suitable for common biz use(io intensive). + * CAUTION: This executor may be not suitable for common biz use(io intensive). * * @return the executor */ diff --git a/cffu-core/src/test/java/io/foldright/demo/AllOfWithResultDemo.java b/cffu-core/src/test/java/io/foldright/demo/AllResultsOfDemo.java similarity index 96% rename from cffu-core/src/test/java/io/foldright/demo/AllOfWithResultDemo.java rename to cffu-core/src/test/java/io/foldright/demo/AllResultsOfDemo.java index 09056bdb..98cbd781 100644 --- a/cffu-core/src/test/java/io/foldright/demo/AllOfWithResultDemo.java +++ b/cffu-core/src/test/java/io/foldright/demo/AllResultsOfDemo.java @@ -12,7 +12,7 @@ import static io.foldright.cffu.CffuFactoryBuilder.newCffuFactoryBuilder; -public class AllOfWithResultDemo { +public class AllResultsOfDemo { public static final ExecutorService myBizExecutor = Executors.newCachedThreadPool(); public static final CffuFactory cffuFactory = newCffuFactoryBuilder(myBizExecutor).build(); @@ -39,7 +39,7 @@ public static void main(String[] args) throws Exception { CompletableFuture cf2 = CompletableFuture.completedFuture(42); CompletableFuture allOf2 = CompletableFuture.allOf(cf1, cf2); - // Result type is Void!! + // Result type is Void! CompletableFuture> allResults2 = CompletableFutureUtils.allResultsOf(cf1, cf2); System.out.println(allResults2.get()); diff --git a/cffu-core/src/test/java/io/foldright/demo/CffuCombineDemo.java b/cffu-core/src/test/java/io/foldright/demo/CffuCombineDemo.java index 9abf93e7..b5b950cb 100644 --- a/cffu-core/src/test/java/io/foldright/demo/CffuCombineDemo.java +++ b/cffu-core/src/test/java/io/foldright/demo/CffuCombineDemo.java @@ -23,9 +23,9 @@ public static void main(String[] args) throws Exception { Cffu cffu1 = cffuFactory.completedFuture("21"); Cffu cffu2 = cffuFactory.completedFuture(42); - Cffu> allOfWithResult = cffu1.cffuCombine(cffu2); + Cffu> combined = cffu1.cffuCombine(cffu2); // or: cffuFactory.cffuCombine(cffu1, cffu2); - System.out.println(allOfWithResult.get()); + System.out.println(combined.get()); ////////////////////////////////////////////////// // or CompletableFutureUtils.combine @@ -33,8 +33,8 @@ public static void main(String[] args) throws Exception { CompletableFuture cf1 = CompletableFuture.completedFuture("21"); CompletableFuture cf2 = CompletableFuture.completedFuture(42); - CompletableFuture> allOfWithResult2 = CompletableFutureUtils.combine(cf1, cf2); - System.out.println(allOfWithResult2.get()); + CompletableFuture> combined2 = CompletableFutureUtils.combine(cf1, cf2); + System.out.println(combined2.get()); //////////////////////////////////////// // cleanup diff --git a/cffu-core/src/test/java/io/foldright/demo/ConcurrencyStrategyDemo.java b/cffu-core/src/test/java/io/foldright/demo/ConcurrencyStrategyDemo.java index ec590a91..604f87a5 100644 --- a/cffu-core/src/test/java/io/foldright/demo/ConcurrencyStrategyDemo.java +++ b/cffu-core/src/test/java/io/foldright/demo/ConcurrencyStrategyDemo.java @@ -18,7 +18,7 @@ public class ConcurrencyStrategyDemo { public static void main(String[] args) throws Exception { //////////////////////////////////////////////////////////////////////// - // CffuFactory#allResultsOfFastFail / allOfFastFail + // CffuFactory#allOfFastFail / allResultsOfFastFail // CffuFactory#anyOfSuccess //////////////////////////////////////////////////////////////////////// final Cffu successAfterLongTime = cffuFactory.supplyAsync(() -> { @@ -29,6 +29,7 @@ public static void main(String[] args) throws Exception { // Result type is Void! Cffu cffuAll = cffuFactory.allOfFastFail(successAfterLongTime, failed); + Cffu> fastFailed = cffuFactory.allResultsOfFastFail(successAfterLongTime, failed); // fast failed without waiting successAfterLongTime System.out.println(fastFailed.exceptionNow()); @@ -37,8 +38,8 @@ public static void main(String[] args) throws Exception { System.out.println(anyOfSuccess.get()); //////////////////////////////////////////////////////////////////////// - // or CompletableFutureUtils#allResultsOfFastFail / allOfFastFail - // CompletableFutureUtils#anyOfSuccess / anyOfSuccess + // or CompletableFutureUtils#allOfFastFail / allResultsOfFastFail + // CompletableFutureUtils#anyOfSuccess //////////////////////////////////////////////////////////////////////// final CompletableFuture successAfterLongTimeCf = CompletableFuture.supplyAsync(() -> { sleep(3000); // sleep LONG time @@ -48,6 +49,7 @@ public static void main(String[] args) throws Exception { // Result type is Void! CompletableFuture cfAll = CompletableFutureUtils.allOfFastFail(successAfterLongTimeCf, failedCf); + CompletableFuture> fastFailedCf = CompletableFutureUtils.allResultsOfFastFail(successAfterLongTimeCf, failedCf); // fast failed without waiting successAfterLongTime System.out.println(CompletableFutureUtils.exceptionNow(fastFailedCf)); diff --git a/cffu-core/src/test/java/io/foldright/demo/DefaultExecutorSettingForCffu.java b/cffu-core/src/test/java/io/foldright/demo/DefaultExecutorSettingForCffu.java index 52f5dece..b7f652ae 100644 --- a/cffu-core/src/test/java/io/foldright/demo/DefaultExecutorSettingForCffu.java +++ b/cffu-core/src/test/java/io/foldright/demo/DefaultExecutorSettingForCffu.java @@ -17,9 +17,9 @@ public static void main(String[] args) { Cffu cf1 = cffuFactory.runAsync(() -> System.out.println("doing a long time work!")); Cffu cf2 = cffuFactory.supplyAsync(() -> { - System.out.println("doing another long time work!!"); + System.out.println("doing another long time work!"); return 42; - }).thenAcceptAsync(i -> System.out.println("doing third long time work!!!")); + }).thenAcceptAsync(i -> System.out.println("doing third long time work!")); cffuFactory.allOf(cf1, cf2).join(); diff --git a/cffu-core/src/test/java/io/foldright/demo/NoDefaultExecutorSettingForCompletableFuture.java b/cffu-core/src/test/java/io/foldright/demo/NoDefaultExecutorSettingForCompletableFuture.java index 85ca39a6..b3c40411 100644 --- a/cffu-core/src/test/java/io/foldright/demo/NoDefaultExecutorSettingForCompletableFuture.java +++ b/cffu-core/src/test/java/io/foldright/demo/NoDefaultExecutorSettingForCompletableFuture.java @@ -9,18 +9,19 @@ public class NoDefaultExecutorSettingForCompletableFuture { public static final ExecutorService myBizExecutor = Executors.newCachedThreadPool(); public static void main(String[] args) { - CompletableFuture cf1 = CompletableFuture.runAsync(() -> System.out.println("doing a long time work!"), + CompletableFuture cf1 = CompletableFuture.runAsync( + () -> System.out.println("doing a long time work!"), myBizExecutor); CompletableFuture cf2 = CompletableFuture .supplyAsync( () -> { - System.out.println("doing another long time work!!"); + System.out.println("doing another long time work!"); return 42; }, myBizExecutor) .thenAcceptAsync( - i -> System.out.println("doing third long time work!!!"), + i -> System.out.println("doing third long time work!"), myBizExecutor); CompletableFuture.allOf(cf1, cf2).join(); diff --git a/cffu-core/src/test/java/io/foldright/showcases/CompletableFutureUsageShowcaseTest.kt b/cffu-core/src/test/java/io/foldright/showcases/CompletableFutureUsageShowcaseTest.kt index 145c0b7a..c4d17d5f 100644 --- a/cffu-core/src/test/java/io/foldright/showcases/CompletableFutureUsageShowcaseTest.kt +++ b/cffu-core/src/test/java/io/foldright/showcases/CompletableFutureUsageShowcaseTest.kt @@ -107,7 +107,7 @@ class CompletableFutureUsageShowcaseTest : FunSpec({ * if executor argument is absent, use default executor of [CompletableFuture.ASYNC_POOL] (normally is a [ForkJoinPool]). * - non-`Async` methods(`thenRun/thenApply`) use the thread of notification; * if there is single previous [CompletableFuture], use the same thread of previous CF. - * CAUTION: restrict the concurrency!! + * CAUTION: restrict the concurrency! */ test("execution thread/executor behavior: then*(non-Async) operations chained after *Async UNCOMPLETED CF, trigger by previous *Async CF complete and run in previous Async CF executor").config( invocations = 100 @@ -129,7 +129,7 @@ class CompletableFutureUsageShowcaseTest : FunSpec({ thenNonAsyncOpThread = currentThread() assertRunInExecutor(testThreadPoolExecutor) - }, testThreadPoolExecutor) // !! switch executor !! + }, testThreadPoolExecutor) // ! switch executor ! .thenApply { // when NOT async, // use same thread of single previous CF @@ -150,7 +150,7 @@ class CompletableFutureUsageShowcaseTest : FunSpec({ .thenRunAsync { // when run ASYNC, // - // - executor is NOT inherited after switch!! + // - executor is NOT inherited after switch! // - use the DEFAULT EXECUTOR of CompletableFuture, if no executor specified. assertNotRunInExecutor(testThreadPoolExecutor) } diff --git a/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CffuExtensions.kt b/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CffuExtensions.kt index d0bff955..f8de3c76 100644 --- a/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CffuExtensions.kt +++ b/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CffuExtensions.kt @@ -64,7 +64,7 @@ private const val ERROR_MSG_FOR_COLL = "no cffuFactory argument provided when th private const val ERROR_MSG_FOR_ARRAY = "no cffuFactory argument provided when this array is empty" /** - * Returns a new Cffu with the results in the same order of all the given Cffus, + * Returns a new Cffu with the results in the **same order** of all the given Cffus, * the new Cffu is completed when all the given Cffus complete. * If any of the given Cffus complete exceptionally, then the returned Cffu * also does so, with a CompletionException holding this exception as its cause. @@ -86,7 +86,7 @@ fun Collection>.allResultsOfCffu(cffuFactory: CffuFactory = ABSE } /** - * Returns a new Cffu with the results in the same order of all the given Cffus, + * Returns a new Cffu with the results in the **same order** of all the given Cffus, * the new Cffu is completed when all the given Cffus complete. * If any of the given Cffus complete exceptionally, then the returned Cffu * also does so, with a CompletionException holding this exception as its cause. @@ -108,7 +108,7 @@ fun Array>.allResultsOfCffu(cffuFactory: CffuFactory = ABSEN } /** - * Returns a new Cffu with the results in the same order of all the given CompletableFutures, + * Returns a new Cffu with the results in the **same order** of all the given CompletableFutures, * the new Cffu is completed when all the given CompletableFutures complete. * If any of the given CompletableFutures complete exceptionally, then the returned Cffu * also does so, with a CompletionException holding this exception as its cause. @@ -125,7 +125,7 @@ fun Collection>.allResultsOfCffu(cffuFactory: CffuF cffuFactory.allResultsOf(*this.toTypedArray()) /** - * Returns a new Cffu with the results in the same order of all the given CompletableFutures, + * Returns a new Cffu with the results in the **same order** of all the given CompletableFutures, * the new Cffu is completed when all the given CompletableFutures complete. * If any of the given CompletableFutures complete exceptionally, then the returned Cffu * also does so, with a CompletionException holding this exception as its cause. @@ -219,7 +219,7 @@ fun Array>.allOfCffu(cffuFactory: CffuFactory): Cffusame order of all the given Cffus, + * Returns a new Cffu with the results in the **same order** of all the given Cffus, * the new Cffu success when all the given Cffus success. * If any of the given Cffus complete exceptionally, then the returned Cffu * also does so *without* waiting other incomplete given Cffus, @@ -242,7 +242,7 @@ fun Collection>.allResultsOfFastFailCffu(cffuFactory: CffuFactor } /** - * Returns a new Cffu with the results in the same order of all the given Cffus, + * Returns a new Cffu with the results in the **same order** of all the given Cffus, * the new Cffu success when all the given Cffus success. * If any of the given Cffus complete exceptionally, then the returned Cffu * also does so *without* waiting other incomplete given Cffus, @@ -265,7 +265,7 @@ fun Array>.allResultsOfFastFailCffu(cffuFactory: CffuFactory } /** - * Returns a new Cffu with the results in the same order of all the given CompletableFutures, + * Returns a new Cffu with the results in the **same order** of all the given CompletableFutures, * the new Cffu success when all the given CompletableFutures success. * If any of the given CompletableFutures complete exceptionally, then the returned Cffu * also does so *without* waiting other incomplete given CompletableFutures, @@ -283,7 +283,7 @@ fun Collection>.allResultsOfFastFailCffu(cffuFactor cffuFactory.allResultsOfFastFail(*this.toTypedArray()) /** - * Returns a new Cffu with the results in the same order of all the given CompletableFutures, + * Returns a new Cffu with the results in the **same order** of all the given CompletableFutures, * the new Cffu success when all the given CompletableFutures success. * If any of the given CompletableFutures complete exceptionally, then the returned Cffu * also does so *without* waiting other incomplete given CompletableFutures, diff --git a/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CompletableFutureExtensions.kt b/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CompletableFutureExtensions.kt index c9ae9c5f..d03a21e6 100644 --- a/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CompletableFutureExtensions.kt +++ b/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CompletableFutureExtensions.kt @@ -31,7 +31,7 @@ import java.util.function.Supplier //////////////////////////////////////// /** - * Returns a new CompletableFuture with the results in the same order of all the given + * Returns a new CompletableFuture with the results in the **same order** of all the given * CompletableFutures, the returned new CompletableFuture is completed when all the given CompletableFutures complete. * If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture * also does so, with a CompletionException holding this exception as its cause. @@ -48,7 +48,7 @@ fun Collection>.allResultsOfCompletableFuture(): Co CompletableFutureUtils.allResultsOf(*this.toTypedArray()) /** - * Returns a new CompletableFuture with the results in the same order of all the given + * Returns a new CompletableFuture with the results in the **same order** of all the given * CompletableFutures, the returned new CompletableFuture is completed when all the given CompletableFutures complete. * If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture * also does so, with a CompletionException holding this exception as its cause. @@ -109,7 +109,7 @@ fun Array>.allOfCompletableFuture(): CompletableFuture< CompletableFuture.allOf(*this) /** - * Returns a new CompletableFuture with the results in the same order of all the given + * Returns a new CompletableFuture with the results in the **same order** of all the given * CompletableFutures, the new CompletableFuture success when all the given CompletableFutures success. * If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture * also does so *without* waiting other incomplete given CompletableFutures, @@ -127,7 +127,7 @@ fun Collection>.allResultsOfFastFailCompletableFutu CompletableFutureUtils.allResultsOfFastFail(*this.toTypedArray()) /** - * Returns a new CompletableFuture with the results in the same order of all the given + * Returns a new CompletableFuture with the results in the **same order** of all the given * CompletableFutures, the new CompletableFuture success when all the given CompletableFutures success. * If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture * also does so *without* waiting other incomplete given CompletableFutures, @@ -491,9 +491,8 @@ fun CompletableFuture.exceptionallyComposeAsync( /** * Waits if necessary for at most the given time for the computation to complete, * and then retrieves its result value when complete, or throws an (unchecked) exception if completed exceptionally. - *

    - * NOTE:
    - * call this method + * + * **NOTE:** call this method * * `result = CompletableFutureUtils.join(cf, timeout, unit);` * @@ -506,8 +505,7 @@ fun CompletableFuture.exceptionallyComposeAsync( * } * ``` * - * CAUTION:
    - * if the wait timed out, this method throws an (unchecked) CompletionException with the TimeoutException as its cause; + * **CAUTION:** if the wait timed out, this method throws an (unchecked) CompletionException with the TimeoutException as its cause; * NOT throws a (checked) TimeoutException like [CompletableFuture.get]. * * @param timeout the maximum time to wait @@ -521,7 +519,7 @@ fun CompletableFuture.join(timeout: Long, unit: TimeUnit): T = /** * Returns the computed result, without waiting. - *

    + * * This method is for cases where the caller knows that the task has already completed successfully, * for example when filtering a stream of Future objects for the successful tasks * and using a mapping operation to obtain a stream of results. @@ -540,7 +538,7 @@ fun CompletableFuture.resultNow(): T = /** * Returns the exception thrown by the task, without waiting. - *

    + * * This method is for cases where the caller knows that the task has already completed with an exception. * * @return the exception thrown by the task diff --git a/demos/cffu-demo/src/main/java/io/foldright/demo/cffu/CffuDemo.java b/demos/cffu-demo/src/main/java/io/foldright/demo/cffu/CffuDemo.java index b3c9dc15..98330985 100644 --- a/demos/cffu-demo/src/main/java/io/foldright/demo/cffu/CffuDemo.java +++ b/demos/cffu-demo/src/main/java/io/foldright/demo/cffu/CffuDemo.java @@ -41,6 +41,7 @@ public static void main(String[] args) throws Exception { final Cffu combined = longTaskA.thenCombine(longTaskB, Integer::sum) .orTimeout(1500, TimeUnit.MILLISECONDS); System.out.println("combined result: " + combined.get()); + final Cffu anyOfSuccess = cffuFactory.anyOfSuccess(longTaskC, longFailedTask); System.out.println("anyOfSuccess result: " + anyOfSuccess.get()); diff --git a/demos/cffu-demo/src/main/java/io/foldright/demo/cffu/CompletableFutureUtilsDemo.java b/demos/cffu-demo/src/main/java/io/foldright/demo/cffu/CompletableFutureUtilsDemo.java index 1e5fe0d3..a91ee65b 100644 --- a/demos/cffu-demo/src/main/java/io/foldright/demo/cffu/CompletableFutureUtilsDemo.java +++ b/demos/cffu-demo/src/main/java/io/foldright/demo/cffu/CompletableFutureUtilsDemo.java @@ -34,8 +34,10 @@ public static void main(String[] args) throws Exception { }, myBizThreadPool); final CompletableFuture combined = longTaskA.thenCombine(longTaskB, Integer::sum); - final CompletableFuture combinedWithTimeout = CompletableFutureUtils.orTimeout(combined, 1500, TimeUnit.MILLISECONDS); + final CompletableFuture combinedWithTimeout = + CompletableFutureUtils.orTimeout(combined, 1500, TimeUnit.MILLISECONDS); System.out.println("combined result: " + combinedWithTimeout.get()); + final CompletableFuture anyOfSuccess = CompletableFutureUtils.anyOfSuccess(longTaskC, longFailedTask); System.out.println("anyOfSuccess result: " + anyOfSuccess.get()); diff --git a/demos/cffu-kotlin-demo/src/main/java/io/foldright/demo/cffu/kotlin/CffuDemo.kt b/demos/cffu-kotlin-demo/src/main/java/io/foldright/demo/cffu/kotlin/CffuDemo.kt index f636b4b6..863f9bf3 100644 --- a/demos/cffu-kotlin-demo/src/main/java/io/foldright/demo/cffu/kotlin/CffuDemo.kt +++ b/demos/cffu-kotlin-demo/src/main/java/io/foldright/demo/cffu/kotlin/CffuDemo.kt @@ -41,6 +41,7 @@ fun main() { val combined = longTaskA.thenCombine(longTaskB, Integer::sum) .orTimeout(1500, TimeUnit.MILLISECONDS) println("combined result: ${combined.get()}") + val anyOfSuccess: Cffu = listOf(longTaskC, longFailedTask).anyOfSuccessCffu() println("anyOfSuccess result: ${anyOfSuccess.get()}")