本文翻译自:http://jaxenter.com/lean-concurrency-in-java-8-49924.htmlhtml
转载请注明出处:http://blog.csdn.net/kingviker/article/details/27057473java
有人之前说过(很是不幸,咱们没有原话了):git
0基础程序猿以为并发很是难。
中级程序猿以为并发很是easy。
高级程序猿以为并发很是难。github
这说的很是对。但是从好的方面来看,经过lambda表达式和很是多改进的API使编写并发代码更easy,Java8并发开发至少能获得改善。让咱们来详细的看看(Java8的改进):sql
java.lang.Thread早在JDK 1.0版本号中就已经存在。在java8中被注解为功能性接口的java.lang.Runnable也是。api
从现在起。差点儿不需要动大脑咱们就可以提交Runnables给一个线程。让咱们若是咱们有一个很是耗时的操做:多线程
public static int longOperation() { System.out.println("Running on thread #" + Thread.currentThread().getId()); // [...] return 42; }
咱们可以用多种方法把这个操做传递给线程,好比:并发
Thread[] threads = { // Pass a lambda to a thread new Thread(() -> { longOperation(); }), // Pass a method reference to a thread new Thread(ThreadGoodies::longOperation) }; // Start all threads Arrays.stream(threads).forEach(Thread::start); // Join all threads Arrays.stream(threads).forEach(t -> { try { t.join(); } catch (InterruptedException ignore) {} });
就像咱们在以前的博文里提到的同样。lambda表达式没有一个简洁的方式来处理被检异常实在是一大憾事。在java.util.function包中新增的功能性接口没有一个涉及到抛出被检异常。把这项工做留给了调用端。oop
在上一篇博文中。咱们已经所以而公布了jOOλ(also jOOL,jOO-Lambda)包,该包包装了JDK中的每一个功能性接口,据有一样功能而且也赞成抛出被检异常。spa
这在使用老的JDK API时特别实用,好比JDBC,或者上面提到的Thread API。使用jOOλ,咱们可以这么写:
// Join all threads Arrays.stream(threads).forEach(Unchecked.consumer( t -> t.join() ));
Java的多线程在Java5的很是好的ExecutorService公布以前一直很是沉寂。管理多线程是一个负担,人们需要额外的库或者一个J2EE/JEE容器来管理线程池。
这些用Java5来处理已经easy了很是多。咱们现在可以提交一个Runnable对象或者一个Callable对象到ExcutorService。它管理本身的线程池。
如下是一个咱们怎样在Java8中利用这些Java5的并发API的样例:
ExecutorService service = Executors .newFixedThreadPool(5); Future[] answers = { service.submit(() -> longOperation()), service.submit(ThreadGoodies::longOperation) }; Arrays.stream(answers).forEach(Unchecked.consumer( f -> System.out.println(f.get()) ));
注意看。咱们是怎样再次使用jOOλ中的UncheckedConsumer来包装在执行期调用get()方法抛出的被检异常。
现在,Java8的Streams API在并发和并行方面有了很是大改进。 在Java8中你可以写出例如如下的代码:
Arrays.stream(new int[]{ 1, 2, 3, 4, 5, 6 }) .parallel() .max() .ifPresent(System.out::println);
尽管在这个特殊的样例中不是很是必要,但看到只调用了parallel()就执行IntStream.max()来启用ForkJoinPool而你没必要操心包括的ForkJoinTasks仍是很是有趣的。这是很是实用的。因为不是每个人均可以接受JDK7该复合物的引入JorkJoin API。