java~并行计算~Future和Callable实现大任务的并行处理
Callable是一个泛型接口,也是一个FunctionalInterface,即函数式接口,它可以使用在Lambda表达式上,即现在比较流行的函数式编程,其实java8之后,封装了好多函数式接口,今天说的Callable它是一个带有返回值的接口,它主要和Future一起使用,用在并行计算上;并行计算就是说,一个大任务,多个线程并发执行,这样可以缩减程序运行的时间,当然前提是你要保持线程的安全性。
大任务实现类
/** * 干一件不好干的事,使用Callable接口,需要 FutureTask实现类的支持,用于接收运算结果. */ class DoWork implements Callable<Integer> { /** * 需要处理的对象集合,每个线程传递自己的对象. */ List<String> list; public DoWork(List<String> list) { this.list = list; } @Override public Integer call() throws Exception { for (String s : list) { System.out.println(Thread.currentThread().getId() + ":" + s); } Thread.sleep(3000); return 1; } }
主方法中拆分大对象,调用大任务方法
@GetMapping("/do-fast") public void doFast() throws InterruptedException, ExecutionException { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ExecutorService executor = Executors.newFixedThreadPool(2); List<Future<Integer>> results = executor.invokeAll(asList( new DoWork(Arrays.asList("a","b")), new DoWork(Arrays.asList("c","d")) )); executor.shutdown(); //合并结果 for (Future<Integer> result : results) { System.out.println(result.get()); } stopWatch.stop(); System.out.println(stopWatch.getLastTaskTimeMillis()); }
如果不使用并行计算,这两个方法执行应该是3秒+3秒=6秒,而使用了并行编程,它只有3秒左右