Java8高中併發

Java8中學併發

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

Java8對JDK 1.0 API的改進。

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()
));

Java8中改進的Java5 API

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中的並行和ForkJoinPool

現在,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

相關文章
相關標籤/搜索