重拾Java基础知识:CompletableFuture

前言

CompletableFuture继承于java.util.concurrent.Future,它本身具备Future的所有特性,以及流式计算、函数式编程、完成通知、自定义异常处理、事件驱动编程模型等很多新的特性。可以用来实现多线程的串行关系,并行关系,聚合关系。使用这种并行方式,极大地提升了程序的表现。

CompletableFuture

创建CompletableFuture

一共有7中方式可以创建CompletableFuture,下面对他们一一进行介绍。

    public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
        return asyncSupplyStage(asyncPool, supplier);
    }
    public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
                                                       Executor executor) {
        return asyncSupplyStage(screenExecutor(executor), supplier);
    }
    
    public static CompletableFuture<Void> runAsync(Runnable runnable) {
        return asyncRunStage(asyncPool, runnable);
    }
    public static CompletableFuture<Void> runAsync(Runnable runnable,
                                                   Executor executor) {
        return asyncRunStage(screenExecutor(executor), runnable);
    }
    
    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);
    }
    public static <U> CompletableFuture<U> completedFuture(U value) {
        return new CompletableFuture<U>((value == null) ? NIL : value);
    }
  • supplyAsync()方法:表示创建带返回值的异步任务,两种方法,第一种只需传入一个Supplier实例;另一种可以指定自定义的线程池,然后将任务提交给该线程池执行,如果不指定,默认使用ForkJoinPool.commonPool()

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("threadName: "+Thread.currentThread().getName());
            return "ok";
        }, Executors.newSingleThreadExecutor());
        String get = completableFuture.get();
        System.out.println(get);
        /** Output:
         * threadName: pool-1-thread-1
         * ok
         */
    }
}
  • runAsync()方法:传参是Runnable类型的,所以没有返回值。可自定义线程池,同supplyAsync()方法类似。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) {
        CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
            System.out.println("threadName: "+Thread.currentThread().getName());
        }, Executors.newSingleThreadExecutor());
        /** Output:
         * threadName: pool-1-thread-1
         */
    }
}
  • allOf()方法:多个任务完成,返回一个全新的已完成CompletableFuture,有一个任务执行异常,调用get()方法时会抛出异常,如果都是正常执行,则返回null。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<String> c1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("task -1");
            return "task -1";
        });
        CompletableFuture<Void> c2 = CompletableFuture.runAsync(()->{
            System.out.println("task -2");
            //throw new RuntimeException(); get方法返回错误信息
        });
        CompletableFuture<String> c3 = CompletableFuture.supplyAsync(()->{
            System.out.println("task -3");
            return "task -3";
        });
        CompletableFuture<Void> completableFuture = CompletableFuture.allOf(c1,c2,c3);
        System.out.println(completableFuture.get());
        /** Output:
         * task -1
         * task -2
         * task -3
         * null
         */
    }
}
  • anyOf()方法:多个任务中任意一个任务完成,返回一个全新的已完成CompletableFuture,如果最快完成的任务执行异常,调用get()方法时会抛出异常,如果都是正常执行,则返回最快完成的任务结果。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<String> c1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("task -1");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "task -1";
        });
        CompletableFuture<Void> c2 = CompletableFuture.runAsync(()->{
            System.out.println("task -2");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        CompletableFuture<String> c3 = CompletableFuture.supplyAsync(()->{
            System.out.println("task -3");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "task -3";
        });
        CompletableFuture<Object> completableFuture = CompletableFuture.anyOf(c1,c2,c3);
        System.out.println(completableFuture.get());
        /** Output:
         * task -1
         * task -2
         * task -3
         * task -3
         */
    }
}
  • completedFuture()方法:给定值,返回一个新的已完成的CompletableFuture

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<String> completableFuture = CompletableFuture.completedFuture("hello");
        String s = completableFuture.get();
        System.out.println(s);
        /** Output:
         * hello
         */
    }
}

获取结果

获取结果有两种方式:get()方法和join()方法。

    public T get() throws InterruptedException, ExecutionException {
        Object r;
        return reportGet((r = result) == null ? waitingGet(true) : r);
    }
    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);
    }
    public T getNow(T valueIfAbsent) {
        Object r;
        return ((r = result) == null) ? valueIfAbsent : reportJoin(r);
    }
    public T join() {
        Object r;
        return reportJoin((r = result) == null ? waitingGet(false) : r);
    }
  • get()方法:等待任务完成后,返回结果或抛出受检测异常。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "test");
        System.out.println(completableFuture.get());
        /** Output:
         * test
         */
        CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {
            throw new RuntimeException();
        });
        System.out.println(completableFuture1.get());
        /** Output:
         * Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.RuntimeException
         * 	at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
         * 	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
         * 	at com.study.test.ExecutorTest.main(ExecutorTest.java:11)
         * Caused by: java.lang.RuntimeException
         * ......
         */
    }
}
  • get(long timeout, TimeUnit unit)方法:指定时间内获取值,超出时长,抛异常。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "test";
        });
        System.out.println(completableFuture.get(1,TimeUnit.SECONDS));
        /** Output:
         * Exception in thread "main" java.util.concurrent.TimeoutException
         * 	at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
         * 	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
         * 	at com.study.test.ExecutorTest.main(ExecutorTest.java:16)
         */
    }
}
  • getNow(T valueIfAbsent)方法:返回结果值等于null,返回指定valueIfAbsent,否则返回已完成任务的结果。。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> null);
        System.out.println(completableFuture.getNow("test"));
        /** Output:
         * test
         */
    }
}
  • join()方法:你以为它是线程里的合并是一样,其实不是。与get()方法一样。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "test");
        System.out.println(completableFuture.join());
        /** Output:
         * test
         */
        CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {
            throw new RuntimeException();
        });
        System.out.println(completableFuture1.join());
        /** Output:
         * Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.RuntimeException
         * 	at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
         * 	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
         * 	at com.study.test.ExecutorTest.main(ExecutorTest.java:11)
         * Caused by: java.lang.RuntimeException
         * ......
         */
    }
}

后续处理

或许你有时候需要在任务执行完成后,进行其它任务的处理,CompletableFuture提供了很多方法,方便你的操作。

单任务结果
  • thenApply()方法:有传参有返回值。上一个任务的执行结果当作参数传入且返回自定义结果

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException{
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            return "任务一";
        }).thenApply(param->{
            System.out.println("thenApply的线程名:"+Thread.currentThread().getName()+",参数:"+param);
            return "thenApply "+ param;
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * thenApply的线程名:main,参数:任务一
         * thenApply 任务一
         */
    }
}
  • thenCompose()方法:有传参有返回值。与thenApply()方法不同,上一个任务的执行结果当作参数传入且返回一个新的任务

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException{
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            return "任务一";
        }).thenCompose((p1) -> {
            System.out.println("thenCombine的线程名:" + Thread.currentThread().getName()+",参数:"+p1);
            return CompletableFuture.supplyAsync(()->"thenCompose");
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * thenCombine的线程名:main,参数:任务一
         * thenCompose
         */
    }
}
  • thenApplyAsync()方法:Async后缀的函数表示需要连接的后置任务会被单独提交到线程池中,从而相对前置任务来说是异步运行的。除此之外,两者没有其他区别。在接下来的介绍中,不讲解Async后缀的方法。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            return "任务一";
        }).thenApplyAsync(param->{
            System.out.println("thenApply的线程名:"+Thread.currentThread().getName()+",参数:"+param);
            return "thenApply "+ param;
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * thenApply的线程名:ForkJoinPool.commonPool-worker-1,参数:任务一
         * thenApply 任务一
         */
    }
}
  • thenAccept()方法:有传参无返回值。上一个任务的执行结果当作参数传入。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            return "任务一";
        }).thenAccept(param->{
            System.out.println("thenApply的线程名:"+Thread.currentThread().getName()+",参数:"+param);
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * thenApply的线程名:main,参数:任务一
         * null
         */
    }
}
  • thenRun()方法:无传参无返回值,上一个任务执行完在执行此任务。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            return "任务一";
        }).thenRun(()->{
            System.out.println("thenApply的线程名:"+Thread.currentThread().getName());
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * thenApply的线程名:main
         * null
         */
    }
}
单任务结果异常
  • handle()方法:有传参有返回值,上一个任务的执行结果或者执行期间抛出的异常(不影响当前任务处理)传递给回调方法,如果是正常执行则执行结果对应的值,异常为null;反之执行结果为null,打印异常信息,返回自定义结果。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            return "任务一";
        }).thenApply((p1) -> {
            System.out.println("thenCombine的线程名:" + Thread.currentThread().getName()+",参数:"+p1);
            Integer a = null;
            return String.valueOf(a *1);
        }).handle((result,erro)->{
            System.out.println("参数:"+result+",异常:"+erro);
            return result;
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * thenCombine的线程名:main,参数:任务一
         * 参数:null,异常:java.util.concurrent.CompletionException: java.lang.NullPointerException
         * null
         */
    }
}
  • whenComplete()方法:有传参无返回值,与 handle()方法无差别,如果该任务正常执行,则get()方法返回上一个任务的执行结果,如果是执行异常,则get()方法抛出异常。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            return "任务一";
        }).thenApply((p1) -> {
            System.out.println("thenCombine的线程名:" + Thread.currentThread().getName()+",参数:"+p1);
            return "thenApply";
        }).whenComplete((result,erro)->{
            System.out.println("参数:"+result+",异常:"+erro);
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * thenCombine的线程名:main,参数:任务一
         * 参数:thenApply,异常:null
         * thenApply
         */
    }
}
  • exceptionally()方法:有参数有返回值。指定某个任务执行异常时执行的回调方法,会将抛出异常作为参数传递到此方法,用此方法返回的结果进行处理。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            return "任务一";
        }).thenApply((p1) -> {
            System.out.println("thenCombine的线程名:" + Thread.currentThread().getName()+",参数:"+p1);
            Integer a= null;
            return a*1;
        }).exceptionally((result)->{
            System.out.println("thenCombine的线程名:" + Thread.currentThread().getName()+",参数:"+result);
            return 0;
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * thenCombine的线程名:main,参数:任务一
         * thenCombine的线程名:main,参数:java.util.concurrent.CompletionException: java.lang.NullPointerException
         * 0
         */
    }
}
双任务结果
  • thenCombine()方法:有传参有返回值,将两个任务的执行结果作为方法入参传递,返回自定义结果。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> c1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            return "任务一";
        });
        CompletableFuture<String> c2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务二的线程名:"+Thread.currentThread().getName());
            return "任务二";
        });
        CompletableFuture<String> completableFuture = c2.thenCombine(c1, (r1, r2) -> {
            System.out.println("thenCombine的线程名:" + Thread.currentThread().getName() + ",参数1:" + r1 + ",参数2:" + r2);
            return r1 + r2;
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * 任务二的线程名:ForkJoinPool.commonPool-worker-1
         * thenCombine的线程名:main,参数1:任务二,参数2:任务一
         * 任务二任务一
         */
    }
}
  • thenAcceptBoth()方法:有传参无返回值,将两个任务的执行结果作为方法入参传递。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> c1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            return "任务一";
        });
        CompletableFuture<String> c2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务二的线程名:"+Thread.currentThread().getName());
            return "任务二";
        });
        CompletableFuture<Void> completableFuture = c2.thenAcceptBoth(c1, (r1, r2) -> {
            System.out.println("thenCombine的线程名:" + Thread.currentThread().getName() + ",参数1:" + r1 + ",参数2:" + r2);
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * 任务二的线程名:ForkJoinPool.commonPool-worker-1
         * thenCombine的线程名:main,参数1:任务二,参数2:任务一
         * null
         */
    }
}
  • runAfterBoth()方法:无传参无返回值,将两个任务执行完后在执行当前任务。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> c1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            return "任务一";
        });
        CompletableFuture<String> c2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务二的线程名:"+Thread.currentThread().getName());
            return "任务二";
        });
        CompletableFuture<Void> completableFuture = c2.runAfterBoth(c1, () -> {
            System.out.println("thenCombine的线程名:" + Thread.currentThread().getName());
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * 任务二的线程名:ForkJoinPool.commonPool-worker-1
         * thenCombine的线程名:main
         * null
         */
    }
}
任意任务结果
  • applyToEither()方法:有传参有返回值,将两个任务中先执行完的任务结果作为方法入参传递,返回自定义结果。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> c1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "任务一";
        });
        CompletableFuture<String> c2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务二的线程名:"+Thread.currentThread().getName());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "任务二";
        });
        CompletableFuture<String> completableFuture = c2.applyToEither(c1, (r1) -> {
            System.out.println("thenCombine的线程名:" + Thread.currentThread().getName()+",参数:"+r1);
            return r1;
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * 任务二的线程名:ForkJoinPool.commonPool-worker-2
         * thenCombine的线程名:ForkJoinPool.commonPool-worker-1,参数:任务一
         * 任务一
         */
    }
}
  • acceptEither()方法:有传参无返回值,将两个任务中先执行完的任务结果作为方法入参传递。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> c1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "任务一";
        });
        CompletableFuture<String> c2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务二的线程名:"+Thread.currentThread().getName());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "任务二";
        });
        CompletableFuture<Void> completableFuture = c2.acceptEither(c1, (r1) -> {
            System.out.println("thenCombine的线程名:" + Thread.currentThread().getName()+",参数:"+r1);
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * 任务二的线程名:ForkJoinPool.commonPool-worker-2
         * thenCombine的线程名:ForkJoinPool.commonPool-worker-1,参数:任务一
         * null
         */
    }
}
  • runAfterEither()方法:无传参无返回值,将两个任务执行完后在执行当前任务。

示例代码:

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CompletableFuture<String> c1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一的线程名:"+Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "任务一";
        });
        CompletableFuture<String> c2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务二的线程名:"+Thread.currentThread().getName());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "任务二";
        });
        CompletableFuture<Void> completableFuture = c2.runAfterEither(c1, () -> {
            System.out.println("thenCombine的线程名:" + Thread.currentThread().getName());
        });
        System.out.println(completableFuture.get());
        /** Output:
         * 任务一的线程名:ForkJoinPool.commonPool-worker-1
         * 任务二的线程名:ForkJoinPool.commonPool-worker-2
         * thenCombine的线程名:ForkJoinPool.commonPool-worker-1
         * null
         */
    }
}

其它方法

  • isDone()方法:判断任务是否完成。三种完成情况:normally(正常执行完毕)、exceptionally(执行异常)、via cancellation(取消)
  • cancel(boolean mayInterruptIfRunning)()方法:取消任务,若一个任务未完成,则以CancellationException异常。其相关未完成的子任务也会以CompletionException结束
  • isCancelled()()方法:是否已取消,在任务正常执行完成前取消,才为true。否则为false
  • 还有其它许多方法,有兴趣自行了解。

本章小结

通常,请谨慎地使用并发。 如果需要使用它,请尝试使用最现代的方法:并行流或 CompletableFutures

如果你的并发问题变得比高级 Java 构造所支持的问题更大且更复杂,请考虑使用专为并发设计的语言,仅在需要并发的程序部分中使用这种语言是有可能的。 在撰写本文时,JVM 上最纯粹的功能语言是 ClojureLisp 的一种版本)和 FregeHaskell 的一种实现)。这些使你可以在其中编写应用程序的并发部分语言,并通过 JVM 轻松地与你的主要 Java 代码进行交互。 或者,你可以选择更复杂的方法,即通过外部功能接口(FFI)将 JVM 之外的语言与另一种为并发设计的语言进行通信。

无论使用特定的语言、库使得并发看起来多么简单,都要将其视为一种妖术,因为总是有东西会在你最不期望出现的时候咬你。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值