欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

CompletableFuture創(chuàng)建及功能使用全面詳解

 更新時(shí)間:2023年07月04日 09:34:51   作者:小成都人  
這篇文章主要為大家介紹了CompletableFuture創(chuàng)建及功能使用全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

FutureTask對(duì)于get()方法容易造成阻塞,所以在其基礎(chǔ)上誕生了CompletableFuture。他們的關(guān)系就像i和i++的關(guān)系,FutureTask能做的,CompletableFuture也能做,并且更加高效,功能更加擴(kuò)展。

創(chuàng)建CompletableFuture

在CompletableFuture源碼注釋中,作者并不希望開發(fā)人員直接使用實(shí)例化去創(chuàng)建CompletableFuture,而是使用四大靜態(tài)方法。

實(shí)例化創(chuàng)建示例:

CompletableFuture completableFuture = new CompletableFuture();

CompletableFuture的四大靜態(tài)方法

supplyAsync(Supplier<U> supplier) ----有返回值

創(chuàng)建帶有返回值的異步任務(wù),類似方法ExecutorServicesubmit(Callable<T> task)方法

CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(() -> {
  System.out.println(Thread.currentThread().getName() + " come in.....");
    int result = ThreadLocalRandom.current().nextInt(10);
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return result;
});

supplyAsync(Supplier<U> supplier,Executor executor)

ExecutorService threadPool = Executors.newFixedThreadPool(3);
// 如果自己沒有創(chuàng)建線程池,則使用默認(rèn)的ForkJoinPool線程池
CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(() -> {
  System.out.println(Thread.currentThread().getName() + " come in.....");
    int result = ThreadLocalRandom.current().nextInt(10);
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return result;
}, threadPool);

runAsync(Runnable runnable)----沒有返回值

創(chuàng)建沒有返回值的異步任務(wù),類似ExecutorService submit(Runnable task)方法

CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
System.out.println(Thread.currentThread().getName() + " come in.....");
    try {
        TimeUnit.MILLISECONDS.sleep(300);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});
System.out.println(runAsync.get());

runAsync(Runnable runnable,Executor executor)

ExecutorService threadPool = Executors.newFixedThreadPool(3);
// 如果沒有指定線程池,則使用默認(rèn)的ForkJoinPool線程池
CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> { System.out.println(Thread.currentThread().getName() + " come in.....");
    try {
        TimeUnit.MILLISECONDS.sleep(300);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}, threadPool);
System.out.println(runAsync.get());

CompletableFuture獲取值

get()

最直接的獲值方法,但會(huì)拋出異常。源碼如下

/**
 * Waits if necessary for this future to complete, and then
 * returns its result.
 * 等待線程計(jì)算完成以后獲取結(jié)果
 * @return the result value
 * @throws CancellationException if this future was cancelled
 * @throws ExecutionException if this future completed exceptionally
 * @throws InterruptedException if the current thread was interrupted
 * while waiting
 */
public T get() throws InterruptedException, ExecutionException {
    Object r;
    return reportGet((r = result) == null ? waitingGet(true) : r);
}

get(long timeout, TimeUnit unit)

如上,但可以加入等待時(shí)間,超過等待時(shí)間,拋出Timeout異常。源碼如下

/**
 * Waits if necessary for at most the given time for this future
 * to complete, and then returns its result, if available.
 * 最多等待給定的時(shí)間以完成此計(jì)算,然后返回其結(jié)果(如果可用)
 * @param timeout the maximum time to wait
 * @param unit the time unit of the timeout argument
 * @return the result value
 * @throws CancellationException if this future was cancelled
 * @throws ExecutionException if this future completed exceptionally
 * @throws InterruptedException if the current thread was interrupted
 * while waiting
 * @throws TimeoutException if the wait timed out
 */
public T get(long timeout, TimeUnit unit)
    throws InterruptedException, ExecutionException, TimeoutException {
    Object r;
    long nanos = unit.toNanos(timeout);
    return reportGet((r = result) == null ? timedGet(nanos) : r);
}

join()

直接獲取值,類似于get(),但與get()不同的是,join()不需要手動(dòng)拋出異常。代碼如下

/**
 * Returns the result value when complete, or throws an
 * (unchecked) exception if completed exceptionally. To better
 * conform with the use of common functional forms, if a
 * computation involved in the completion of this
 * CompletableFuture threw an exception, this method throws an
 * (unchecked) {@link CompletionException} with the underlying
 * exception as its cause.
 * 完成時(shí)返回結(jié)果值,如果異常完成則拋出(未選中)異常。
 * 為了更好地符合通用函數(shù)形式的使用,如果完成此CompletableFuture所涉及的計(jì)算引發(fā)異常,
 * 則此方法將引發(fā)(未選中){@link CompletionException},其原因是基礎(chǔ)異常。
 *
 * @return the result value
 * @throws CancellationException if the computation was cancelled
 * @throws CompletionException if this future completed
 * exceptionally or a completion computation threw an exception
 */
public T join() {
    Object r;
    return reportJoin((r = result) == null ? waitingGet(false) : r);
}

getNow(T valueIfAbsent)

和join()相同,不需要手動(dòng)拋出異常,在執(zhí)行過程中會(huì)返回遇見的異常。不同的是可以給定默認(rèn)值,如果執(zhí)行錯(cuò)誤或未完成,返回給定的默認(rèn)值。源碼如下

/**
 * Returns the result value (or throws any encountered exception)
 * if completed, else returns the given valueIfAbsent.
 * 如果計(jì)算完成,則返回結(jié)果值(或引發(fā)任何遇到的異常),否則返回給定的默認(rèn)值
 * @param valueIfAbsent the value to return if not completed
 * @return the result value, if completed, else the given valueIfAbsent
 * @throws CancellationException if the computation was cancelled
 * @throws CompletionException if this future completed
 * exceptionally or a completion computation threw an exception
 */
public T getNow(T valueIfAbsent) {
    Object r;
    return ((r = result) == null) ? valueIfAbsent : reportJoin(r);
}

complete

通俗來說,在complete之前設(shè)定一個(gè)等待時(shí)間,如果在等待時(shí)間內(nèi)沒有計(jì)算出結(jié)果,則返回true,并返回complete給定的默認(rèn)值。反之為false,返回原定計(jì)算的值。源碼如下

/**
 * If not already completed, sets the value returned by {@link
 * #get()} and related methods to the given value.
 *
 * @param value the result value
 * @return {@code true} if this invocation caused this CompletableFuture
 * to transition to a completed state, else {@code false}
 */
public boolean complete(T value) {
    boolean triggered = completeValue(value);
    postComplete();
    return triggered;
}

示例:

CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
    try {
        TimeUnit.SECONDS.sleep(2);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "123";
});
try {
    TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {
    e.printStackTrace();
}
System.out.println(completableFuture.complete("給定的默認(rèn)值") + "\t" + completableFuture.join());

返回結(jié)果:

true 給定的默認(rèn)值

CompletableFuture的回調(diào)

其中,帶Async后綴的函數(shù)表示需要連接的后置任務(wù)會(huì)被單獨(dú)提交到線程池中,從而相對(duì)前置任務(wù)來說是異步運(yùn)行的。除此之外,兩者沒有其他區(qū)別。

thenApply / thenAccept / thenRun互相依賴

thenApply()-----有入?yún)⒂蟹祷?/h2>

表示獲取上一個(gè)任務(wù)的執(zhí)行結(jié)果作為新任務(wù)的執(zhí)行參數(shù),有返回值。但遇見錯(cuò)誤時(shí)會(huì)終止后面所有的線程。

通俗來說,任務(wù)A執(zhí)行完執(zhí)行B,B需要A的結(jié)果,并且B有返回值

thenApply也是有三個(gè)方法重載

// 后一個(gè)任務(wù)與前一個(gè)任務(wù)在同一線程執(zhí)行
public <U> CompletableFuture<U> thenApply(
    Function<? super T,? extends U> fn) {
    return uniApplyStage(null, fn);
}
// 后一個(gè)任務(wù)與前一個(gè)任務(wù)在不同線程中執(zhí)行
public <U> CompletableFuture<U> thenApplyAsync(
    Function<? super T,? extends U> fn) {
    return uniApplyStage(defaultExecutor(), fn);
}
//后一個(gè)任務(wù)使用自定義線程池執(zhí)行
public <U> CompletableFuture<U> thenApplyAsync(
    Function<? super T,? extends U> fn, Executor executor) {
    return uniApplyStage(screenExecutor(executor), fn);
}

ps:示例

ExecutorService threadPool = Executors.newFixedThreadPool(3);
CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(() -> {
    System.out.println(Thread.currentThread().getName() + " come in.....");
    int result = ThreadLocalRandom.current().nextInt(10);
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return result;
}, threadPool);
// 承接上一個(gè)多線程,有返回值
CompletableFuture<Integer> thenApply = supplyAsync.thenApply((result) -> {
    System.out.println("上一線程結(jié)果" + result);
    return ThreadLocalRandom.current().nextInt(10);
});
System.out.println(thenApply.get());
threadPool.shutdown();

如果沒用使用thenApplyAsync()指定自己的線程池,線程池依舊使用的是默認(rèn)的ForkJoinPool線程池。

thenAccept() ----有入?yún)o返回

消費(fèi)型回調(diào)。接受上一個(gè)任務(wù)的結(jié)果作為參數(shù),但是沒有返回值。

通俗來說,任務(wù)A執(zhí)行完執(zhí)行B,B需要A的結(jié)果,B沒有返回值

// 后一個(gè)任務(wù)與前一個(gè)任務(wù)在同一線程執(zhí)行
public CompletableFuture<Void> thenAccept(Consumer<? super T> action) {
    return uniAcceptStage(null, action);
}
// 后一個(gè)任務(wù)與前一個(gè)任務(wù)在不同線程中執(zhí)行
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action) {
    return uniAcceptStage(defaultExecutor(), action);
}
//后一個(gè)任務(wù)使用自定義線程池執(zhí)行
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action,
                                               Executor executor) {
    return uniAcceptStage(screenExecutor(executor), action);
}

示例:

public static void main(String[] args) {
    ExecutorService threadPool = Executors.newFixedThreadPool(2);
    CompletableFuture<Void> async = CompletableFuture.supplyAsync(() -> {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("111111");
        return 1;
    }, threadPool).thenApplyAsync((f) -> {
        // 手動(dòng)創(chuàng)建異常
        System.out.println("222222");
        f += 2;
        return f;
    }, threadPool).thenAcceptAsync(f -> {
        f += 3;
        System.out.println("最終的值:" + f);
    }, threadPool);
    System.out.println(Thread.currentThread().getName() + " 先去做其他事情了");
    async.join();
    threadPool.shutdown();
}

ps:只消費(fèi)

thenRun()----無入?yún)o返回

thenRun 的方法沒有入?yún)?,也沒有返回值。

通俗來說,任務(wù)A執(zhí)行完執(zhí)行B,并且B不需要A的結(jié)果,B沒有返回值

示例:

public static void main(String[] args) {
    ExecutorService threadPool = Executors.newFixedThreadPool(2);
    CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "123";
    },threadPool);
    completableFuture.thenRunAsync(() -> {
        System.out.println("thenRun 無入?yún)?,無返回值");
    },threadPool);
    completableFuture.join();
    threadPool.shutdown();
}

小結(jié)

thenApply()、thenAccept()、thenRun()的區(qū)別,示例代碼如下:

System.out.println(CompletableFuture.supplyAsync(()->"resultA").thenRun(()->{}).join());
System.out.println("《-----------------------------》");
System.out.println(CompletableFuture.supplyAsync(()->"resultA").thenAccept(System.out::println).join());
System.out.println("《-----------------------------》");
System.out.println(CompletableFuture.supplyAsync(()->"resultA").thenApply((f)-> "resultB").join());

結(jié)果:

null

《------------------------------------------》

resultA

null

《-------------------------------------------》

resultB

exceptionally()

如果執(zhí)行任務(wù)出現(xiàn)異常,則執(zhí)行 exceptionally 中的代碼塊,并且需要一個(gè)返回值。

示例:

public static void main(String[] args) throws Exception {
    CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
        System.out.println(Thread.currentThread().getName() + " come in.....");
        int a = 10 / 0;
        return 1;
    });
    //whenComplete:參數(shù)列表 (T t, U u),如果執(zhí)行過程正常完成,則執(zhí)行該分支
    System.out.println(completableFuture.whenComplete((t, u) -> {
        if (u==null) {
            System.out.println(t);
        }
        //exceptionally :如果執(zhí)行過程出現(xiàn)異常,則走該分支
    }).exceptionally((f) -> {
        System.out.println("異常詳細(xì)信息:" + f.getMessage());
        return 500;
    }).get());
}

whenComplete()

whenComplete 算是 exceptionallythenApply的結(jié)合,將任務(wù)執(zhí)行的結(jié)果和異常作為回到方法的參數(shù),如果沒有發(fā)生異常則異常參數(shù)為null。源碼如下:

public CompletableFuture<T> whenComplete(
    BiConsumer<? super T, ? super Throwable> action) {
    return uniWhenCompleteStage(null, action);
}
public CompletableFuture<T> whenCompleteAsync(
    BiConsumer<? super T, ? super Throwable> action) {
    return uniWhenCompleteStage(asyncPool, action);
}
public CompletableFuture<T> whenCompleteAsync(
    BiConsumer<? super T, ? super Throwable> action, Executor executor) {
    return uniWhenCompleteStage(screenExecutor(executor), action);
}

示例:

ExecutorService threadPool = Executors.newFixedThreadPool(3);
        // 自定義線程池,可以防止主線程立刻結(jié)束,導(dǎo)致守護(hù)線程forkjoin的問題
        try {
            CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(() ->{
                System.out.println(Thread.currentThread().getName() + " come in.....");
                int result = ThreadLocalRandom.current().nextInt(10);
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return result;
            }, threadPool).whenComplete((v,e) -> {
                if (e==null) { 
                    System.out.println(Thread.currentThread().getName() + " come in.....");
                    System.out.println("上一個(gè)線程執(zhí)行的結(jié)果:" + v);
                }
            }).exceptionally(e -> {
                e.printStackTrace();
                System.out.println("上一個(gè)線程執(zhí)行的異常" + e);
                return null;
            });
            System.out.println(Thread.currentThread().getName() + " 忙其他的去了.....");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }

執(zhí)行結(jié)果:

handle()

表示獲取上一個(gè)任務(wù)的執(zhí)行結(jié)果作為新任務(wù)的執(zhí)行參數(shù),有返回值。相對(duì)于thenApply(),handle()可以將異常帶入下一個(gè)線程處理。源碼如下

public <U> CompletableFuture<U> handle(
    BiFunction<? super T, Throwable, ? extends U> fn) {
    return uniHandleStage(null, fn);
}

示例:

public static void main(String[] args) {
    ExecutorService threadPool = Executors.newFixedThreadPool(2);
    CompletableFuture<Integer> handle = CompletableFuture.supplyAsync(() -> {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("111111");
        return 1;
    }, threadPool).handle((f, n) -> {
        // 手動(dòng)創(chuàng)建異常,跳過此線程后面的動(dòng)作
        int i = 10/0;
        System.out.println("222222");
        f += 2;
        return f;
    }).handle((f, n) -> {
        // 如果檢測(cè)到上一線程有異常,可以處理
        if (n!=null) {
            f=10;
        }
        System.out.println("333333");
        f += 3;
        return f;
    }).whenComplete((f,e) -> {
        if (e==null) {
            System.out.println("計(jì)算結(jié)果為:" + f);
        }
    }).exceptionally(e -> {
        e.printStackTrace();
        System.out.println(e.getMessage());
        return null;
    });
    System.out.println(Thread.currentThread().getName() + " 先去做其他事情了");
    handle.join();
    threadPool.shutdown();
}

運(yùn)行結(jié)果:

main 先去做其他事情了
111111
333333
計(jì)算結(jié)果為:13

CompletableFuture對(duì)計(jì)算速度的選用

使用applyToEither可對(duì)兩個(gè)線程執(zhí)行速度進(jìn)行比較,獲取速度最快的執(zhí)行結(jié)果。源碼如下

public <U> CompletableFuture<U> applyToEither(
    CompletionStage<? extends T> other, Function<? super T, U> fn) {
    return orApplyStage(null, other, fn);
}
public <U> CompletableFuture<U> applyToEitherAsync(
    CompletionStage<? extends T> other, Function<? super T, U> fn) {
    return orApplyStage(asyncPool, other, fn);
}
public <U> CompletableFuture<U> applyToEitherAsync(
    CompletionStage<? extends T> other, Function<? super T, U> fn,
    Executor executor) {
    return orApplyStage(screenExecutor(executor), other, fn);
}

示例:

CompletableFuture<String> supplyAsyncA = CompletableFuture.supplyAsync(() -> {
    try {
        TimeUnit.SECONDS.sleep(2);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "playA";
});
CompletableFuture<String> supplyAsyncB = CompletableFuture.supplyAsync(() -> {
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "playB";
});
CompletableFuture<String> applyToEither = supplyAsyncA.applyToEither(supplyAsyncB, f -> {
    return f + " is winner!";
});
System.out.println(Thread.currentThread().getName() + "----" + applyToEither.join());

applyToEither、acceptEitherrunAfterEither的區(qū)別與前面回調(diào)函數(shù)的區(qū)別一致,在于是否有返回值

thenAcceptBoth

當(dāng)兩個(gè)CompletionStage都執(zhí)行完成后,把結(jié)果一塊交給thenAcceptBoth來進(jìn)行消耗

applyToEither

兩個(gè)CompletionStage,誰(shuí)執(zhí)行返回的結(jié)果快,我就用那個(gè)CompletionStage的結(jié)果進(jìn)行下一步的轉(zhuǎn)化操作。

acceptEither

兩個(gè)CompletionStage,誰(shuí)執(zhí)行返回的結(jié)果快,我就用那個(gè)CompletionStage的結(jié)果進(jìn)行下一步的消耗操作。

runAfterEither

兩個(gè)CompletionStage,任何一個(gè)完成了都會(huì)執(zhí)行下一步的操作(Runnable)

runAfterBoth

兩個(gè)CompletionStage,都完成了計(jì)算才會(huì)執(zhí)行下一步的操作(Runnable)

CompletableFuture多任務(wù)合并

thenCombine

thenCompose 方法允許你對(duì)兩個(gè) CompletionStage 進(jìn)行流水線操作,第一個(gè)操作完成時(shí),將其結(jié)果作為參數(shù)傳遞給第二個(gè)操作。,源碼如下

public <U,V> CompletableFuture<V> thenCombine(
    CompletionStage<? extends U> other,
    BiFunction<? super T,? super U,? extends V> fn) {
    return biApplyStage(null, other, fn);
}
public <U,V> CompletableFuture<V> thenCombineAsync(
    CompletionStage<? extends U> other,
    BiFunction<? super T,? super U,? extends V> fn) {
    return biApplyStage(asyncPool, other, fn);
}
public <U,V> CompletableFuture<V> thenCombineAsync(
    CompletionStage<? extends U> other,
    BiFunction<? super T,? super U,? extends V> fn, Executor executor) {
    return biApplyStage(screenExecutor(executor), other, fn);
}

示例:

CompletableFuture<Integer> integerCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
    System.out.println("線程一。。。。。。啟動(dòng)");
    try {
        TimeUnit.SECONDS.sleep(2);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return 10;
});
CompletableFuture<Integer> integerCompletableFuture2 = CompletableFuture.supplyAsync(() -> {
    System.out.println("線程二。。。。。。啟動(dòng)");
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return 20;
});
CompletableFuture<Integer> result = integerCompletableFuture1.thenCombine(integerCompletableFuture2, (x, y) -> {
    System.out.println("開始合并。。。。。。。。");
    return x + y;
});
System.out.println(result.join());

結(jié)果:

線程一。。。。。。啟動(dòng)
線程二。。。。。。啟動(dòng)
開始合并。。。。。。。。
30

allof

等待所有任務(wù)完成。源碼如下:

public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) {
    return andTree(cfs, 0, cfs.length - 1);
}

示例:

ExecutorService threadPool = Executors.newFixedThreadPool(2);
 CompletableFuture<String> integerCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
                System.out.println("線程一。。。。。。啟動(dòng)");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "華為";
        },threadPool);
        CompletableFuture<String> integerCompletableFuture2 = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
                System.out.println("線程二。。。。。。啟動(dòng)");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "小米";
        },threadPool);
        CompletableFuture<Void> allOf = CompletableFuture.allOf(integerCompletableFuture1, integerCompletableFuture2);
        System.out.println(integerCompletableFuture1.join());
        System.out.println(integerCompletableFuture2.join());
        System.out.println("main..........end.........");
        threadPool.shutdown();

因?yàn)?code>allof需要等待所有線程執(zhí)行完畢,所以會(huì)先打印線程二。并等待線程一執(zhí)行完畢。

結(jié)果:

線程二。。。。。。啟動(dòng)
線程一。。。。。。啟動(dòng)
華為
小米
main..........end.........

anyof

等待其中一個(gè)任務(wù)完成。源碼如下:

public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) {
    return orTree(cfs, 0, cfs.length - 1);
}

示例(在任務(wù)合并時(shí)不同,將allof改為anyof):

CompletableFuture<Object> anyOf = CompletableFuture.anyOf(integerCompletableFuture1, integerCompletableFuture2);
System.out.println(anyOf.join());
System.out.println("main..........end.........");
threadPool.shutdown();

因?yàn)榫€程二的執(zhí)行比線程一快,所以直接打印線程二。anyof返回的CompletableFuture,存儲(chǔ)的時(shí)先完成線程的返回結(jié)果。

結(jié)果:

線程二。。。。。。啟動(dòng)
小米
main..........end.........
線程一。。。。。。啟動(dòng)

以上就是CompletableFuture創(chuàng)建及功能使用全面詳解的詳細(xì)內(nèi)容,更多關(guān)于CompletableFuture功能創(chuàng)建的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • idea?intellij快速修復(fù)if語(yǔ)句缺少大括號(hào)的問題

    idea?intellij快速修復(fù)if語(yǔ)句缺少大括號(hào)的問題

    這篇文章主要介紹了idea?intellij快速修復(fù)if語(yǔ)句缺少大括號(hào)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • springboot集成開發(fā)實(shí)現(xiàn)商場(chǎng)秒殺功能

    springboot集成開發(fā)實(shí)現(xiàn)商場(chǎng)秒殺功能

    這篇文章主要介紹了springboot集成實(shí)現(xiàn)商品秒殺功能,秒殺系統(tǒng)業(yè)務(wù)流程,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Spring實(shí)現(xiàn)IoC的多種方式小結(jié)

    Spring實(shí)現(xiàn)IoC的多種方式小結(jié)

    本篇文章主要介紹了Spring實(shí)現(xiàn)IoC的多種方式小結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-02-02
  • SpringBoot熔斷機(jī)制之CircuitBreaker詳解

    SpringBoot熔斷機(jī)制之CircuitBreaker詳解

    這篇文章主要介紹了SpringBoot熔斷機(jī)制之CircuitBreaker詳解,SpringBoot的熔斷機(jī)制在微服務(wù)架構(gòu)中扮演著重要角色,其中CircuitBreaker是其核心機(jī)制之一,用于防止服務(wù)的異常狀態(tài)影響到整個(gè)系統(tǒng)的運(yùn)作,需要的朋友可以參考下
    2023-10-10
  • Java回溯法解決全排列問題流程詳解

    Java回溯法解決全排列問題流程詳解

    從n個(gè)不同元素中任取m(m≤n)個(gè)元素,按照一定的順序排列起來,叫做從n個(gè)不同元素中取出m個(gè)元素的一個(gè)排列。當(dāng)m=n時(shí)所有的排列情況叫全排列。這篇文章主要介紹了Java回溯法解決全排列問題
    2022-10-10
  • Java報(bào)錯(cuò)java.awt.AWTException: AWT的解決方法

    Java報(bào)錯(cuò)java.awt.AWTException: AWT的解決方法

    在Java圖形用戶界面(GUI)編程中,java.awt.AWTException是一個(gè)常見的異常,它通常與AWT(Abstract Window Toolkit)組件相關(guān),這個(gè)異常可能在嘗試進(jìn)行與窗口、圖形環(huán)境或系統(tǒng)剪貼板等操作時(shí)拋出,本文將詳細(xì)探討AWTException的成因,并提供多種解決方案
    2024-12-12
  • SpringBoot集成SOL鏈的詳細(xì)過程

    SpringBoot集成SOL鏈的詳細(xì)過程

    Solanaj 是一個(gè)用于與 Solana 區(qū)塊鏈交互的 Java 庫(kù),它為 Java 開發(fā)者提供了一套功能豐富的 API,使得在 Java 環(huán)境中可以輕松構(gòu)建與 Solana 區(qū)塊鏈交互的應(yīng)用程序,這篇文章主要介紹了SpringBoot集成SOL鏈的詳細(xì)過程,需要的朋友可以參考下
    2025-01-01
  • Maven安裝本地的jar包和創(chuàng)建帶模板的自定義項(xiàng)目的操作過程

    Maven安裝本地的jar包和創(chuàng)建帶模板的自定義項(xiàng)目的操作過程

    這篇文章主要介紹了Maven安裝本地的jar包和創(chuàng)建帶模板的自定義項(xiàng)目,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-03-03
  • Fastjson 常用API介紹及下載地址(推薦)

    Fastjson 常用API介紹及下載地址(推薦)

    Fastjson是一個(gè)Java語(yǔ)言編寫的高性能功能完善的JSON庫(kù)。接下來通過本文給大家分享Fastjson 常用API介紹及下載地址,感興趣的朋友一起看看吧
    2017-11-11
  • 解析Spring?漏洞及其修復(fù)方案

    解析Spring?漏洞及其修復(fù)方案

    官宣了最近網(wǎng)傳的Spring漏洞。攻擊者利用該漏洞,可在未授權(quán)的情況下遠(yuǎn)程執(zhí)行命令,今天通過本文給大家普及下漏洞分析影響范圍及解決方案,感興趣的朋友跟隨小編一起看看吧
    2022-04-04

最新評(píng)論