Java8中的简易并发

Wesley13
• 阅读 752

Java8中的简易并发 

分享到: 5

本文由 ImportNew - kingviker 翻译自 jaxenter。欢迎加入Java小组。转载请参见文章末尾的要求。

有人曾经说过(很抱歉,我们找不到原句了):

初级程序员认为并发很难。

中级程序员认为并发很简单。

高级程序员认为并发很难。

这说的很对。但是从好的方面来看,Java8为我们带来了转机,通过lambda表达式和改进的API可以使得编写并发代码更容易。让我们来具体的看看Java8的改进吧:

Java8对JDK 1.0 API的改进

java.lang.Thread早在JDK 1.0版本中就已经存在。在java8中被注解为功能性接口的java.lang.Runnable也是。

从现在起,几乎不需要动大脑我们就可以提交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包中新增的功能性接口都不会抛出被检查异常,把这项工作留给了调用端。

在上一篇博文中,我们已经因此而发布了jOOλ(also jOOL,jOO-Lambda)包,该包包装了JDK中的每一个功能性接口,具有相同功能而且也允许抛出被检异常。这在使用老的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来处理已经容易了很多。我们现在可以提交一个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。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Wesley13 Wesley13
3年前
Java8中的简易并发
我们在《实战Java高并发程序设计》一书中,专门介绍过java8中对并发的改进。这里我通过转载一篇博客来说简单介绍下。有人曾经说过(很抱歉,我们找不到原句了):初级程序员认为并发很难。中级程序员认为并发很简单。高级程序员认为并发很难。这说的很对。但是从好的方面来看,Java8为我们带来了转机,通过lamb
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
达里尔 达里尔
1年前
给数组添加新数据,判断数据是否重复
多选要进行数组拼接,希望判断往原数组里添的新数据是否重复,封装个简易方法languageconstdataArrayname:'aaa',id:1,name:'bbb',id:2;constnewDataname:'ccc',id:2;//要添加的新数
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这