突然想看一下异步,想起之前用CompletableFuture ,记一下
使用
1 方法异步调用:
CompletableFuture<Student> future1 = CompletableFuture.supplyAsync(
()->{
Service s = new Service();
return s.s1("1");
}
);
这个是需要获取返回对象调用方法,入参是Supplier ,最后或获得CompletableFuture 一个future对象,如果运行方法,不需要返回,可使用CompletableFuture runAsync(Runnable runnable) ,返回void
默认的使用ForkJoinPool 线程池,也可以自己指定线程池,好控制线程数
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
Executor executor) {
return asyncSupplyStage(screenExecutor(executor), supplier);
}
2 获取执行结果
(1) 阻塞 (使用的调用线程获取结果)
future.get();
(2)使用异步线程非阻塞(使用的异步执行线程执行回调)
future.thenAccept(Consumer<? super T> action)
有一系列的then方法,对结果运算还可以再用异步线程
future3.thenAcceptBoth(future1.thenAcceptBoth(future2,(student1,student2)->{
System.out.println(Thread.currentThread().getName()+" 获取结果 "+System.currentTimeMillis()+"------2--------"+student2);
System.out.println(Thread.currentThread().getName()+" 获取结果 "+System.currentTimeMillis()+"------1--------"+student1);
}
),((student, aVoid) ->
System.out.println(Thread.currentThread().getName()+" 获取结果 "+System.currentTimeMillis()+"------3--------"+student)
));
模拟
写一个简单的future例子:
1 future 需要满足的是:用异步线程执行supplier方法,返回一个futuere,提供一个get方法,可以阻塞到获取结果
提供一个类似监听的方式,使用异步线程进行后续操作:
package com.lambda.parallel.myFuture;
import java.util.ArrayList;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class MyFuture<T> {
T result;
ArrayList<Consumer> consumers = new ArrayList<>();
static <T> MyFuture asyncExc(Supplier<T> supplier, Executor executor){
MyFuture<T> myFuture = new MyFuture<>();
executor.execute(()->{
myFuture.result = supplier.get();
myFuture.changeStatus(true);
});
return myFuture;
}
//获取的future
T get(){
try {
while (result == null){
Thread.sleep(100);
}
return result;
}catch (Exception e){
e.printStackTrace();
}
return get();
}
void thenExe(Consumer<T> consumer){
this.consumers.add(consumer);
if(result!= null) {
consumer.accept(result);
consumers.remove(consumer);
}
}
void changeStatus(boolean f){
if(f){
consumers.forEach(consumer -> consumer.accept(result));
}
}
}
测试:
package com.lambda.parallel.myFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MyFutureTest {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(2);
MyFuture<String> future1 = MyFuture.asyncExc(()->{
try {
System.out.println(Thread.currentThread().getName()+" "+System.currentTimeMillis()+"------1");
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "11";
},pool);
MyFuture<String> future2 = MyFuture.asyncExc(()->{
try {
System.out.println(Thread.currentThread().getName()+" "+System.currentTimeMillis()+"------2");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "222";
},pool);
MyFuture<String> future3 = MyFuture.asyncExc(()->{
// try {
System.out.println(Thread.currentThread().getName()+" "+System.currentTimeMillis()+"------2");
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
return "333";
},pool);
// System.out.println(Thread.currentThread().getName()+" 获取结果 "+System.currentTimeMillis()+"------1--------"+future1.get());
// System.out.println(Thread.currentThread().getName()+" 获取结果 "+System.currentTimeMillis()+"------2--------"+future2.get());
future1.thenExe(s-> System.out.println(Thread.currentThread().getName()+" 获取结果 "+System.currentTimeMillis()+"------1--------"+s));
future2.thenExe(s-> System.out.println(Thread.currentThread().getName()+" 获取结果 "+System.currentTimeMillis()+"------2--------"+s));
future3.thenExe(s-> System.out.println(Thread.currentThread().getName()+" 获取结果 "+System.currentTimeMillis()+"------3--------"+s));
}
}