目录
- 一、Future接口
- 二、CompletionStage接口
-
- 1、串行执行,方法前缀then和runAfterBoth方法
-
- 1)、thenRun方法,前一阶段结果不影响,无返回
- 2)、thenAccept方法,前一阶段结果变入参,无返回
- 3)、thenApply方法,前一阶段结果变入参,有返回
- 4)、thenCombine方法,前一阶段 f1 和 f2 的结果变入参,有返回
- 5)、thenAcceptBoth方法(和thenCombine方法一样,只是无返回)
- 6)、runAfterBoth方法(和thenCombine方法一样,只是无返回、无入参)
- 7)、thenCompose方法(和thenApply方法一样,只是传入函数的返回是CompletableFuture<>)
- 8)、whenComplete方法,入参多了一个异常,无返回值
- 9)、handle方法,和whenComplete方法一样,多了返回值
- 2、前一阶段的两个任务中,只需完成一个就执行后面的
- 3、异常处理
- 三、多线程学习笔记
一、Future接口
java.util.concurrent包下,有以下方法:
- cancel(boolean var1):取消Callable任务,未开始或已完成返回false,boolean参数表示是否中断执行中的Callable任务
- isCanceled():判断Callable任务是否取消了
- isDone():判断是否完成
- get():获得Callable的返回值
- get(long time, TimeUnit unit):设置超时时间,防止无限时间的等待
二、CompletionStage接口
java.util.concurrent包下,jdk1.8才引入。用于阶段处理,实现链式的阶段型的操作,使线程与线程之间可以愉快的进行对话。目前只有CompletableFuture一个实现类。
1、串行执行,方法前缀then和runAfterBoth方法
后缀带Async,可以用线程池异步处理,默认线程池ForkJoinPool,3个一组,共27个方法:
1)、thenRun方法,前一阶段结果不影响,无返回
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main线程start");
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程名称:" + Thread.currentThread().getName());
return 1;
}).thenRunAsync(() -> {
System.out.println("线程名称:" + Thread.currentThread().getName());
}, EXECUTOR_SERVICE);
future.get();
System.out.println("main线程end");
}
输出结果:
2)、thenAccept方法,前一阶段结果变入参,无返回
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main线程start");
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程名称:" + Thread.currentThread().getName());
return 1;
}).thenAccept((t) -> {
System.out.println("线程名称:" + Thread.currentThread().getName());
System.out.println(t);
});
future.get();
System.out.println("main线程end");
}
输出结果:
3)、thenApply方法,前一阶段结果变入参,有返回
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main线程start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程名称:" + Thread.currentThread().getName());
return 1;
}).thenApply((t) -> {
System.out.println("线程名称:" + Thread.currentThread().getName());
System.out.println(t);
return t;
});
Integer t = future.get();
System.out.println("返回结果:" + t);
System.out.println("main线程end");
}
输出结果:
4)、thenCombine方法,前一阶段 f1 和 f2 的结果变入参,有返回
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main线程start");
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("f1线程名称:" + Thread.currentThread().getName());
return 1;
});
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("f2线程名称:" + Thread.currentThread().getName());
return 2;
}).thenCombine(f1, (t, u) -> {
System.out.println("结合后线程名称:" + Thread.currentThread().getName());
System.out.println("t:" + t);
System.out.println("u:" + u);
return t + u;
});
Integer result = f2.get();
System.out.println("返回结果:" + result);
System.out.println("main线程end");
}
输出结果:
5)、thenAcceptBoth方法(和thenCombine方法一样,只是无返回)
6)、runAfterBoth方法(和thenCombine方法一样,只是无返回、无入参)
7)、thenCompose方法(和thenApply方法一样,只是传入函数的返回是CompletableFuture<>)
8)、whenComplete方法,入参多了一个异常,无返回值
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main线程start");
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("f1线程名称:" + Thread.currentThread().getName());
// return 1;
throw new RuntimeException("异常了!");
}).whenComplete((t, u) -> {
System.out.println("f2线程名称:" + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (u != null) {
System.out.println("异常1");
u.printStackTrace();
} else {
System.out.println("接收到结果:" + t);
}
}).thenCompose((t) -> {
System.out.println("thenCompose线程名称:" + Thread.currentThread().getName());
System.out.println(t);
return CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("f3线程名称:" + Thread.currentThread().getName());
return 2;
});
}).exceptionally((t) -> {
System.out.println("f4线程名称:" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异常2");
t.printStackTrace();
return 3;
});
Integer result = f1.get();
System.out.println("返回结果:" + result);
System.out.println("main线程end");
}
输出结果:
9)、handle方法,和whenComplete方法一样,多了返回值
2、前一阶段的两个任务中,只需完成一个就执行后面的
1)、applyToEither方法,只需要前一阶段其中一个任务执行完,就会执行,并将其结果作为入参,有返回值
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main线程start");
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("f1线程名称:" + Thread.currentThread().getName());
return 1;
});
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("f2线程名称:" + Thread.currentThread().getName());
return 2;
}).applyToEither(f1, (t) -> {
System.out.println("结合后线程名称:" + Thread.currentThread().getName());
System.out.println("t:" + t);
return t;
});
Integer result = f2.get();
System.out.println("返回结果:" + result);
System.out.println("main线程end");
}
输出结果:
2)、acceptEither方法(和applyToEither方法一样,只是无返回)
3)、runAfterEither方法(和applyToEither方法一样,只是无返回、无入参)
3、异常处理
1)、exceptionally方法,捕获异常
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main线程start");
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("f1线程名称:" + Thread.currentThread().getName());
throw new RuntimeException("异常了!");
}).thenCompose((t) -> {
System.out.println("thenCompose线程名称:" + Thread.currentThread().getName());
System.out.println(t);
return CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("f2线程名称:" + Thread.currentThread().getName());
return 2;
});
}).exceptionally((t) -> {
System.out.println("f3线程名称:" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.printStackTrace();
return 3;
});
Integer result = f1.get();
System.out.println("返回结果:" + result);
System.out.println("main线程end");
}
输出结果: