q7goodies事例_Java 8 Friday Goodies:精益并发

q7goodies事例

Data Geekery ,我们喜欢Java。 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 我们已经写了一些关于Java 8好东西的博客 ,现在我们觉得是时候开始一个新的博客系列了,……

Java 8星期五

每个星期五,我们都会向您展示一些不错的教程风格的Java 8新功能,这些功能利用了lambda表达式,扩展方法和其他出色的功能。 您可以在GitHub上找到源代码

Java 8 Goodie:精益并发

曾经有人说过(不幸的是,我们没有消息来源了):

初级程序员认为并发很难。
经验丰富的程序员认为并发很容易。
高级程序员认为并发很难。

没错 但好的一面是,Java 8至少会通过使使用lambda和许多改进的API编写并发代码更加容易而至少会改善性能。 让我们仔细看看:

Java 8在JDK 1.0 API上的改进

从JDK 1.0开始就已经存在java.lang.Threadjava.lang.Runnable也是如此,它将在Java 8中用FunctionalInterface进行注释。

从现在开始,如何最终将Runnable提交到Thread几乎是不费吹灰之力。 假设我们有一个长期运行的操作:

public static int longOperation() {
    System.out.println("Running on thread #"
       + Thread.currentThread().getId());

    // [...]
    return 42;
}

然后,我们可以通过各种方式将此操作传递给Threads ,例如

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包中新添加的功能接口均不允许抛出已检查的异常,从而将工作留给了调用站点。
jool-logo-黑色
因此,在上一篇文章中 ,我们发布了jOOλ(也称为jOOL,jOO-Lambda) ,它将每个JDK的功能接口包装在一个等效的功能接口中,该功能接口允许引发检查异常。 这对于旧的JDK API(例如JDBC)或上述Thread API尤其有用。 使用jOOλ ,我们可以这样写:

// Join all threads
Arrays.stream(threads).forEach(Unchecked.consumer(
    t -> t.join()
));

Java 8在Java 5 API上的改进

在Java 5出色的ExecutorService发行之前,Java的多线程API一直处于Hibernate状态。 管理线程一直是一个负担,人们需要外部库或J2EE / JEE容器来管理线程池。 使用Java 5可以轻松得多。现在,我们可以 RunnableCallable 提交ExecutorService ,后者可以管理自己的线程池。

这是一个示例,说明如何在Java 8中利用这些Java 5并发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()调用引发的已检查异常包装在RuntimeException

Java 8中的并行和ForkJoinPool

现在,Java 8 Streams API在并发性和并行性方面发生了很多变化。 例如,在Java 8中,您可以编写以下代码:

Arrays.stream(new int[]{ 1, 2, 3, 4, 5, 6 })
      .parallel()
      .max()
      .ifPresent(System.out::println);

尽管在这种特殊情况下没有必要,但仍然有趣的是,仅调用parallel() 即可在您的JDK内部ForkJoinPool的所有可用线程上运行IntStream.max() reduce操作,而无需担心涉及ForkJoinTasks 。 这可能非常有用,因为并非所有人都欢迎JDK 7 ForkJoin API引入的复杂性

在这篇有趣的InfoQ文章中了解有关Java 8并行流的更多信息。

有关Java 8的更多信息

并行是新Streams API背后的主要驱动力之一。 在许多情况下,能够仅在Stream上设置一个名为parallel()的标志是非常了不起的。

在上一个示例中,我们看到了OptionalInt.ifPresent()方法,该方法在先前的reduce操作成功的情况下执行IntConsumer参数。

其他语言,例如Scala,都知道一种“选项”类型可以改善NULL处理。 我们之前已在博客上介绍了Optional ,我们将在Java 8 Streams的上下文中重申Java 8 Optional类型,敬请期待!

同时,请查看Eugen Paraschiv出色的Java 8资源页面

翻译自: https://www.javacodegeeks.com/2014/03/java-8-friday-goodies-lean-concurrency.html

q7goodies事例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值