本文翻譯自: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。