关于多线程CompletableFuture的使用

CompletableFuture.runAsync(Runnable runnable);
CompletableFuture.runAsync(Runnable runnable, Executor executor);
 
CompletableFuture.supplyAsync(Supplier<U> supplier);
CompletableFuture.supplyAsync(Supplier<U> supplier, Executor executor)

runAsync 方法接收的是 Runnable 的实例,意味着它没有返回值
supplyAsync 方法对应的是有返回值的情况
这两个方法的带 executor 的变种,表示让任务在指定的线程池中执行,不指定的话,通常任务是在 ForkJoinPool.commonPool() 线程池中执行的。

CompletableFuture.runAsync(() -> {}).thenRun(() -> {}); 
CompletableFuture.runAsync(() -> {}).thenAccept(resultA -> {}); 
CompletableFuture.runAsync(() -> {}).thenApply(resultA -> "resultB");
 
CompletableFuture.supplyAsync(() -> "resultA").thenRun(() -> {});
CompletableFuture.supplyAsync(() -> "resultA").thenAccept(resultA -> {});
CompletableFuture.supplyAsync(() -> "resultA").thenApply(resultA -> resultA + " resultB");

前面 3 行代码演示的是,任务 A 无返回值,所以对应的,第 2 行和第 3 行代码中,resultA 其实是 null。

第 4 行用的是 thenRun(Runnable runnable),任务 A 执行完执行 B,并且 B 不需要 A 的结果。

第 5 行用的是 thenAccept(Consumer action),任务 A 执行完执行 B,B 需要 A 的结果,但是任务 B 不返回值。

第 6 行用的是 thenApply(Function fn),任务 A 执行完执行 B,B 需要 A 的结果,同时任务 B 有返回值。

这一小节说完了,如果任务 B 后面还有任务 C,往下继续调用 .thenXxx() 即可。

public CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn);
public <U> CompletionStage<U> handle(BiFunction<? super T, Throwable, ? extends U> fn);

上面的代码中,任务 A、B、C、D 依次执行,如果任务 A 抛出异常(当然上面的代码不会抛出异常),那么后面的任务都得不到执行。如果任务 C 抛出异常,那么任务 D 得不到执行。

那么我们怎么处理异常呢?看下面的代码,我们在任务 A 中抛出异常,并对其进行处理:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    throw new RuntimeException();
})
        .exceptionally(ex -> "errorResultA")
        .thenApply(resultA -> resultA + " resultB")
        .thenApply(resultB -> resultB + " resultC")
        .thenApply(resultC -> resultC + " resultD");
 
System.out.println(future.join());
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "resultA")
        .thenApply(resultA -> resultA + " resultB")
        // 任务 C 抛出异常
        .thenApply(resultB -> {throw new RuntimeException();})
        // 处理任务 C 的返回值或异常
        .handle(new BiFunction<Object, Throwable, Object>() {
            @Override
            public Object apply(Object re, Throwable throwable) {
                if (throwable != null) {
                    return "errorResultC";
                }
                return re;
            }
        })
        .thenApply(resultC -> resultC + " resultD");
 
System.out.println(future.join());
如果是批量的任务
 无返回值的情况下使用
CompletableFuture.allOf()
有返回值使用,但是只会返回首先执行完的那一个
CompletableFuture.anyOf

上边都是抄袭,以下是我写的demo

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
// 这个是线程池
public class ThreadPoolUtils {

    public static ExecutorService threadPool = new ThreadPoolExecutor(1, 10, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000), Executors.defaultThreadFactory(),
            //当任务队列已满而且线程超过最大线程数,任务的拒绝策略
            new ThreadPoolExecutor.AbortPolicy());
}
// 任务
public class Componet implements Callable<Car>{
	private Car car;
	public Componet(Car c) {
		car= c;
	}
	public Car call() throws Exception {
		// TODO Auto-generated method stub
		car.setName(car.getColor()+"|"+car.getLonger());
		return car;
	}
}
// 这个是传统写法
public class Test01 {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		List<Car> cars = getCars();
		List<Callable<Car>> tasks = new ArrayList<Callable<Car>>();
		for (int i = 0; i < cars.size(); i++) {
			TimeUnit.MILLISECONDS.sleep(100);
			System.out.println("加1");
			tasks.add(new Componet(cars.get(i)));
		}
		List<Future<Car>> invokeAll = ThreadPoolUtils.threadPool.invokeAll(tasks);
		for (Future<Car> future : invokeAll) {
			System.out.println(future.get());
		}
		 ThreadPoolUtils.threadPool.shutdown();
	}

	public static List<Car> getCars(){
		List<Car> list=new ArrayList<Car>();
		list.add(Car.add("红色1", "50"));
		list.add(Car.add("蓝色2", "10"));
		list.add(Car.add("黄色3", "90"));
		list.add(Car.add("绿色4", "70"));
		list.add(Car.add("青色5", "80"));
		list.add(Car.add("白色6", "10"));
		list.add(Car.add("黑色7", "20"));
		list.add(Car.add("红色8", "50"));
		list.add(Car.add("蓝色9", "10"));
		list.add(Car.add("黄色10", "90"));
		list.add(Car.add("绿色11", "70"));
		list.add(Car.add("青色12", "80"));
		list.add(Car.add("白色13", "10"));
		list.add(Car.add("黑色14", "20"));
		list.add(Car.add("红色15", "50"));
		list.add(Car.add("蓝色16", "10"));
		list.add(Car.add("黄色17", "90"));
		list.add(Car.add("绿色18", "70"));
		list.add(Car.add("青色19", "80"));
		list.add(Car.add("白色20", "10"));
		list.add(Car.add("黑色21", "20"));
		return list;
	}
}
// 这个是completableFuture
public class Test02 {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		List<Car> cars = getCars();
		Queue<Car> cars1 =new ArrayBlockingQueue<>(1000);
		for (Car car : cars) {
			TimeUnit.MILLISECONDS.sleep(100);
			System.out.println("加1");
			Car car1 = CompletableFuture.supplyAsync(()->{
				Componet componet2 = new Componet(car);
				 Car call = null;
				try {
					call = componet2.call();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return call;
			},ThreadPoolUtils.threadPool).get();
			cars1.add(car1);
		}
		cars1.forEach(System.out::println);
	}

	public static List<Car> getCars(){
		List<Car> list=new ArrayList<Car>();
		list.add(Car.add("红色1", "50"));
		list.add(Car.add("蓝色2", "10"));
		list.add(Car.add("黄色3", "90"));
		list.add(Car.add("绿色4", "70"));
		list.add(Car.add("青色5", "80"));
		list.add(Car.add("白色6", "10"));
		list.add(Car.add("黑色7", "20"));
		list.add(Car.add("红色8", "50"));
		list.add(Car.add("蓝色9", "10"));
		list.add(Car.add("黄色10", "90"));
		list.add(Car.add("绿色11", "70"));
		list.add(Car.add("青色12", "80"));
		list.add(Car.add("白色13", "10"));
		list.add(Car.add("黑色14", "20"));
		list.add(Car.add("红色15", "50"));
		list.add(Car.add("蓝色16", "10"));
		list.add(Car.add("黄色17", "90"));
		list.add(Car.add("绿色18", "70"));
		list.add(Car.add("青色19", "80"));
		list.add(Car.add("白色20", "10"));
		list.add(Car.add("黑色21", "20"));
		return list;
	}
}
public class Test03 {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		threadDemo3();
	}
	
	public static void threadDemo() throws InterruptedException, ExecutionException {
		final CompletableFuture<String> futureOne = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                System.out.println("futureOne InterruptedException");
            }
            return "futureOneResult";
        });
        final CompletableFuture<String> futureTwo = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(6000);
            } catch (InterruptedException e) {
                System.out.println("futureTwo InterruptedException");
            }
            return "futureTwoResult";
        });
//        CompletableFuture future = CompletableFuture.allOf(futureOne, futureTwo);
//        System.out.println(future.get());
        CompletableFuture completableFuture = CompletableFuture.anyOf(futureOne, futureTwo);
        System.out.println(completableFuture.get());
	}
	
	
	public static void threadDemo1() throws InterruptedException, ExecutionException {
		CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(()->{
			try {
				TimeUnit.SECONDS.sleep(5);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return "success";
		},ThreadPoolUtils.threadPool);
		String string = null;
		while(string==null) {
			System.out.println("----------------");
			string = supplyAsync.getNow(string);
			System.out.println(string);
		}
		System.out.println("-------结束------------------");
		System.out.println(string);
	}
	
	
	public static void threadDemo2() throws InterruptedException, ExecutionException {
		CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(()->{
			//int j=1/0;
			try {
				
				System.out.println("开始");
				TimeUnit.SECONDS.sleep(5);
				System.out.println("重新开始");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return "success";
		},ThreadPoolUtils.threadPool);
		supplyAsync.whenComplete((e,k)->{
			System.out.println("等等");
			System.out.println("e:"+e);
			System.out.println("k:"+k);
		});
		
		
		String string = CompletableFuture.supplyAsync(()->{
			try {
				System.out.println("开始");
				TimeUnit.SECONDS.sleep(5);
				System.out.println("重新开始");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return "success111111";
		},ThreadPoolUtils.threadPool).get();
		System.out.println(string);
	}
	
	
	public static void threadDemo3() {
		
		CompletableFuture<Void> runAsync = CompletableFuture.runAsync(()->{
			System.out.println("第一");
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("第三");
		});
		runAsync.thenRun(()->{
			System.out.println("子任务");
		});
//		runAsync.whenComplete()
		/*
		 * runAsync.whenCompleteAsync((e,k)->{ System.out.println("子任务");
		 * System.out.println(e); System.out.println(k); System.out.println("子任务结束");
		 * });
		 */		
		System.out.println("第二");
		try {
			TimeUnit.SECONDS.sleep(5);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
// 异常的demo
public class Test04 {
	public static void main(String[] args) throws IOException {
		 CompletableFuture completableFuture = CompletableFuture.completedFuture("默认值").thenApplyAsync(x -> {
	         System.out.println("上一个老哥给我返回了: " + x);
	         System.out.println(1 / 0);
	         return "上面的老哥别出错,不然我完不成我的任务了";
	     }).thenApplyAsync((y) -> {
	         System.out.println("上一个老哥给我返回了: " + y);
	         return "哈哈,我完成了";
	     }).exceptionally((Throwable ex) -> {// 这里的 ex 和上面的 s 采用了不同的写法,s 是省略返回值类型的,我只想说:“不写返回值类型的话,我想屎!”“妈爷贼~简写是真的写的快,真香~”
	         System.out.println(ex.getMessage());
	         return "我出错了";
	     });
	     try {
	         Thread.sleep(100L);// 给与上面异步代码 100 毫秒运行时间,以便其完成
	     } catch (InterruptedException e) {
	         e.printStackTrace();
	     }
	     System.out.println(completableFuture.getNow("我还没完成"));
	     System.in.read();
	}
}
public class Test05 {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		System.out.println("进入餐厅");
		System.out.println("点餐");
		
//		  CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(()->{
//			  System.out.println("厨师做了一盘蛋炒饭"); 
//			  System.out.println("吃饭");
//			  return "蛋炒饭";
//		  }).thenCompose(e->CompletableFuture.supplyAsync(()->{
//			  System.out.println("客人说不要"+e); 
//			  System.out.println("盛了一碗米饭"); 
//			  return e+"米饭";
//		  }));
		 
//		CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(()->{
//			try {
//				TimeUnit.SECONDS.sleep(2);
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//			System.out.println("厨师做了一盘蛋炒饭");
//			return "蛋炒饭";
//		}).thenCombine(CompletableFuture.supplyAsync(()->{
//			try {
//				TimeUnit.SECONDS.sleep(1);
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//			System.out.println("客人说不要蛋炒饭");
//			System.out.println("盛了一碗米饭");
//			return "米饭";
//		}), (a,b)->{
//			System.out.println("-----------------------");
//			System.out.println("a:"+a+"|"+"b:"+b);
//			System.out.println("-----------------------");
//			return b;
//		});
		
//		  CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(()->{
//			  try {
//				TimeUnit.SECONDS.sleep(1);
//			} catch (InterruptedException e1) {
//				// TODO Auto-generated catch block
//				e1.printStackTrace();
//			}
//			  System.out.println(Thread.currentThread().getName());
//			  System.out.println("厨师做了一盘蛋炒饭"); 
//			  System.out.println("吃饭");
//			  return "蛋炒饭";
//		  }).thenApplyAsync(e->{
//			  System.out.println(Thread.currentThread().getName());
//			  System.out.println("客人说不要"+e); 
//			  System.out.println("盛了一碗米饭"); 
//			  return e+"米饭";
//		  });
		
//		System.out.println("吃了一盘"+supplyAsync.get());
//		System.out.println("离开餐厅了");
	}
}
public class Test06 {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		
		System.out.println("下班了");
		 CompletableFuture<String> applyToEither = CompletableFuture.supplyAsync(()->{
			 int i = 1/0;
		
			return "300路";
		 }).applyToEither(CompletableFuture.supplyAsync(()->{
			 try {
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			 return "800路";
		 }).applyToEither(CompletableFuture.supplyAsync(()->{
			 try {
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			 return "700路";
		 }), i->i),fi->fi).exceptionally(e->{
			 return "出租车";
		 });
		System.out.println("坐"+applyToEither.get()+"回家");
		
	}
}

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Test07 {
	public static void main(String[] args) throws InterruptedException, ExecutionException, IOException {
		System.out.println("开始");
		List<CompletableFuture> list=new ArrayList<>();
		List<Integer> collect = IntStream.rangeClosed(1, 20).boxed().collect(Collectors.toList());
		for (Integer integer : collect) {
			CompletableFuture<String> thenApplyAsync = CompletableFuture.supplyAsync(()->{
				System.out.println(Thread.currentThread().getName());
				return integer;
			},ThreadPoolUtils.threadPool).thenApplyAsync(e->{
				try {
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				String str="第"+integer+"天上班";
				System.out.println(Thread.currentThread().getName());
				return str;
			},ThreadPoolUtils.threadPool);
			list.add(thenApplyAsync);
		}
		for (Integer integer : collect) {
			CompletableFuture<String> thenComposeAsync = CompletableFuture.supplyAsync(()->{
				System.out.println(Thread.currentThread().getName());
				return integer+"份蛋炒饭";
			},ThreadPoolUtils.threadPool).thenComposeAsync(e->CompletableFuture.supplyAsync(()->{
				try {
					TimeUnit.SECONDS.sleep(5);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName());
				return integer+"杯水";
			},ThreadPoolUtils.threadPool));
			list.add(thenComposeAsync);
		}
		System.out.println("以上是主线程");
		CompletableFuture[] array = list.stream().toArray(CompletableFuture[]::new);
		System.out.println("执行多线程任务");
		CompletableFuture.allOf(array).join();
		System.out.println("多线程任务执行完毕");
		System.out.println("取结果");
		for (CompletableFuture completableFuture : array) {
			System.out.println(completableFuture.get());
		}
		System.out.println("取结果完毕");
		System.out.println("结束");
		System.in.read();
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值