パワフルCompletableFuture

プライマー

CPU作業の効率を最大にするように、プログラムをより効率的にするために、我々は、非同期プログラミングを使用します。最初に考えたのは、特定の仕事をするために、新しいスレッドを開くことです。さらに、ステージ上でメイン物事の糸、ひいては未来を告げる値を返すことができ、新しいスレッドをできるようにするためです。冷却するためのコールバック関数がある場合は、方法は、メインスレッドは、今後の取り組みのお問い合わせ新しいスレッドにより提供されます。したがって、Java8を上にして、いくつかの後悔、強力なCompletableFuture未来を満たすためです。

未来

従来のマルチスレッドプログラムは、すべての後に、CPUが完全に動作できるようにすることができますが、唯一では、新たにもう一度あなたのメインスレッドをスレッド気にすることなく、開かれた、より効率的に、非同期することができます。たとえば、あなたが新しいスレッドを開くだけで1 + ... + nは計算すると、結果を印刷します。時には、あなたは子供が結果をスレッド返す必要が、さらに計算がメインスレッド上で行われた、私たちは未来を必要としています。

以下の例を参照して、メインスレッドは、2 + 4 + 8 + 10 + 6を算出し、1 + 3 + 5 + 7 + 9子スレッドを計算するステップと、最後に二つの部分の結果がメインスレッドに再び追加されます。

public class OddNumber implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        Thread.sleep(3000);
        int result = 1 + 3 + 5 + 7 + 9;
        return result;
    }
}
复制代码
public class FutureTest {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();
        OddNumber oddNumber = new OddNumber();
        Future<Integer> future = executor.submit(oddNumber);
        long startTime = System.currentTimeMillis();
        int evenNumber = 2 + 4 + 6 + 8 + 10;
        try {
            Thread.sleep(1000);
            System.out.println("0.开始了:"+ (System.currentTimeMillis()-startTime) +"秒");
            int oddNumberResult = future.get();//这时间会被阻塞
            System.out.println("1+2+...+9+10="+(evenNumber+oddNumberResult));
            System.out.println("1.开始了:"+ (System.currentTimeMillis()-startTime) +"秒");
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}
输出结果:
0.开始了:1001秒
1+2+...+9+10=55
1.开始了:3002秒
复制代码

見て今後 5比較的単純なだけで、インタフェース

//取消任务,如果已经完成或者已经取消,就返回失败
boolean cancel(boolean mayInterruptIfRunning);
//查看任务是否取消
boolean isCancelled();
//查看任务是否完成
boolean isDone();
//刚才用到了,查看结果,任务未完成就一直阻塞
V get() throws InterruptedException, ExecutionException;
//同上,但是加了一个过期时间,防止长时间阻塞,主线程也做不了事情
V get(long timeout, TimeUnit unit)
    throws InterruptedException, ExecutionException, TimeoutException;
复制代码

CompletableFuture

私たちのメインスレッドがメインと呼ばれているので、非常に豊かな未来を見ないために上記の5つの方法は、彼らがイニシアチブを取る必要があり、私は物事が私を知らせるためのイニシアチブをとる終了する子スレッドを願っています。このため、Java8はCompletableFuture、今後の実装クラスをもたらしました。実際には、最も魅力的な場所は大幅な機能の未来を豊かにしますが、新機能のJava8の流れを兼ね備えていないCompletableFuture。

コールバックを実装し、自動追従運転

CompletableFutureがコールバックを実装してどのような方法(1)事前に言ってやる:thenAccept()

    public CompletableFuture<Void> thenAccept(Consumer<? super T> action) {
        return uniAcceptStage(null, action);
    }
复制代码

、Java8に新機能を使用して、パラメータ化された行動は、必ずしも基本的なパラメータの型やクラスではないパラメータ消費者があり、また、(行動)の機能、または方法(インターフェース)することができます。

public class OddNumberPlus implements Supplier<Integer> {
    @Override
    public Integer get() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 1+3+5+7+9;
    }
}
复制代码
public class CompletableFutureTest {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        final int evenNumber = 2 + 4 + 6 + 8 + 10;
        CompletableFuture<Integer> oddNumber = CompletableFuture.supplyAsync(new OddNumberPlus());
        try {
            Thread.sleep(1000);
            System.out.println("0.开始了:"+ (System.currentTimeMillis()-startTime) +"秒");
            //看这里,实现回调
            oddNumber.thenAccept(oddNumberResult->
                        {
                            System.out.println("1.开始了:"+ (System.currentTimeMillis()-startTime) +"秒");
                            System.out.println("此时计算结果为:"+(evenNumber+oddNumberResult));
                        });
            oddNumber.get();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}
输出结果:
0.开始了:1006秒
1.开始了:3006秒
此时计算结果为:55
复制代码

これは、タスクを作成するには、接続プールを示していない。この場合には、その言及する価値がある、プログラムは)(デフォルトタスクの接続プールForkJoinPool.commonPoolを選択します

    private static final Executor asyncPool = useCommonPool ?
        ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
复制代码

ForkJoinPoolは、分岐/結合フレームと呼ばれる、JDK7を開始しました。タスクは、異なるストリームが形成され、再帰的なタスクにより多くの分子に分割することができるパラレルも強い伴う、実行ワークスチールアルゴリズム。効率を大幅に向上させます。もちろん、あなたはまた、独自の接続プールを指定することができます。

CompletableFuture合併

Java8は確かに一見将来、実際には、CompletableFuture機能を行う、そこに誰もが使用する多くの方法が、上記の例はあるが、将来実現、CompletableFutureを豊かに。結局のところ、あなたはこれがブロックされていないとき、私は非常に将来の戻り値を得、その後、手動で(このmainメソッドは非常に不快でなければなりませんが)いくつかのアクションのことを行うことができますget()メソッドを使用しCompletableFuture。そして、次のことは、行わ将来は非常に面倒になります。私たちは、どのように我々はそれを必要としないmainメソッドだけ偶奇コレクションプラスこの操作のコレクション、二つのサブスレッドへの2つのコレクションを事前に考えられた操作は非同期と仮定しますか?二つのスレッドの終了がカウントされるまではい、開いた2つのスレッドが、我々は最終的にあなたが子スレッドが最終的にそれを終了したことを知っていますか、疑問があり、追加されましたか?豊富なCompletableFuture関数は、2つのオーバーサブスレッド待ちのための方法を提供してくれます(...あなたは世論調査、不確実な通話のisDone()このメソッドを作ることができるように見える)、そして操作を追加します。

    //asyncPool就是上面提到的默认线程池ForkJoinPool
    public <U,V> CompletableFuture<V> thenCombineAsync(
        CompletionStage<? extends U> other,
        BiFunction<? super T,? super U,? extends V> fn) {
        return biApplyStage(asyncPool, other, fn);
    }
复制代码

例を見てください:

public class OddCombine implements Supplier<Integer> {
    @Override
    public Integer get() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 1+3+5+7+9;
    }
}
复制代码
public class EvenCombine implements Supplier<Integer> {
    @Override
    public Integer get() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 2+4+6+8+10;
    }
}

复制代码
public class CompletableCombineTest {
    public static void main(String[] args) throws Exception{
        CompletableFuture<Integer> oddNumber = CompletableFuture.supplyAsync(new OddCombine());
        CompletableFuture<Integer> evenNumber = CompletableFuture.supplyAsync(new EvenCombine());
        long startTime = System.currentTimeMillis();
        CompletableFuture<Integer> resultFuturn = oddNumber.thenCombine(evenNumber,(odd,even)->{
            return odd + even;
        });
        System.out.println(resultFuturn.get());
        System.out.println("0.开始了:"+ (System.currentTimeMillis()-startTime) +"秒");
    }
}
输出结果:
55
0.开始了:3000秒
复制代码

シミュレートされた睡眠1秒の側、寝て3秒が、リアルタイムのネットワーク要求は不明です。とてもクールではない、ジューシーな現象ではありませんが、上記の操作はJava8の流れの概念を利用してきました。

二つのサブスレッドが十分ではありません、そこ** anyOff()**機能、複数のCompletableFutureに耐えることができ、すべてのタスクが完了するまで待機します。

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

長いような、方法があり、第一の端部が、最後まで、タスクはもはや待っていないの後ろに、それは十分条件とみなすことができたときに実行されます。

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

長いOddNumberPlus上記の例では、変調方式の時間とに基づいて:

public class OddNumberPlus implements Supplier<Integer> {
    @Override
    public Integer get() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 1+3+5+7+9;
    }
}
复制代码
public class CompletableCombineTest {
    public static void main(String[] args) throws Exception{
        CompletableFuture<Integer> oddNumber = CompletableFuture.supplyAsync(new OddCombine());
        CompletableFuture<Integer> evenNumber = CompletableFuture.supplyAsync(new EvenCombine());
        CompletableFuture<Integer> testNumber = CompletableFuture.supplyAsync(new OddNumberPlus());
        long startTime = System.currentTimeMillis();
        CompletableFuture<Object> resultFuturn = CompletableFuture.anyOf(oddNumber,evenNumber,testNumber);
        System.out.println(resultFuturn.get());
        System.out.println("0.开始了:"+ (System.currentTimeMillis()-startTime) +"秒");
    }
}
输出结果:
30
0.开始了:1000秒
复制代码

概要

)thenApply()コールバック関数を除いて外部添加することができ、ならびにthenApply(;多くの方法は、例えば、CompletableFuture事実がある一般runAsync()、類似supplyAsync()が、ノーリターン値を使用するにもrunAfterBothを()、注射しました名前を知って見ることが意図されてrunAfterEither()、。多くのがありますが、私たちは、ソースは、このクラスを詳しく見てCompletableFuture開くように指すことができます。唯一のJavaがGengshuangを書くことができないであろう、CompletableFutureを通じて、Java8はなど、より強力な、強力なストリーミングコンセプト、パラメータ化された行動、効率的な並列概念を、感じて、コーナーの周りを参照してください、Javaはまた、全体の生態系を豊かにし続けています。Javaは進行中で、それは時代によって排除されていないされてきた、我々はJavaerは一緒に彼のキャリアはJavaのおかげで、進捗状況を続けることができます。

おすすめ

転載: juejin.im/post/5d307367e51d455d850d3ba4