超越线程池:Java并发并没有你想的那么糟糕

简介:

很多人一直唠叨着并发中的新概念。然而,许多开发人员还没有机会把过多的注意力都放在上面。在这篇文章中,我们将带您了解Java 8 streams、 Hadoop、 Apache Spark、 Quasar fibers以及响应式编程,让你迅速入门。尤其是如果你不经常用它们的话。一句话,它并不遥远,它就在我们身边。

超越线程池:Java并发并没有你想的那么糟糕

我们该怎么做?

谈到并发,一种很好的方式来形容当前的问题是来回答几个小问题以便更好的了解它:

它是一个数据处理任务么?如果是这样的话,它可以分解为独立的任务单元么?

操作系统、虚拟机和你的代码之间的关系是什么?(本地线程 VS 轻量级线程)

有多少机器和处理器参与?(单核 VS 多核)

让我们带着问题,一起找出每个问题的最佳答案吧。

1、从线程池到并行流

在Java 8中,我们了解到新的流API接口,它允许应用聚集操作,如筛选、排序或者映射数据流。流允许我们做的另一件事情是,在多核机器上应用并行操作。并行流 ——通过把Fork/Join框架引入Java 7将线程间的工作分离。Java 6并发库,我们看到了ExecutorService创建和处理我们的工作线程池,这不得不说是个进步。

Fork/Join也建立在ExecutorService之上,与传统的线程主要的区别在于如何在线程和支持多核的机器间分配工作。用一个简单的 ExecutorService你能完全控制工作线程之间的负载分布,确立每个任务的大小以便线程来处理。而Fork/Join,恰好有个work-stealing算法分配线程间的负载。简而言之,这允许大型任务可以被分成更小单元,并在不同的线程间处理,最终我们可以知道——它是为了平衡线程间的 工作。然而,这并不是万能的。

有时并行流会减慢你速度的,所以你需要多想想。在你的方法中使用parallelStream会导致瓶颈和减速(在我们基准测试中跑慢了约15%左右)。假设我们已经运行多个线程,在其中一些我们使用parallelStream,在线程池中添加越来越多的线程。这可以很容易超过我们的核心处理能力,由于增加了上下文转换一切都慢下来了。

小结:在单机上并行流使线程处理抽象化,在一定程度上这会均衡核心间的负载。然而,如果你想高效使用它们,记住硬件是关键而不是生产更多的线程而超出机器的处理能力。

2、Apache Hadoop和Apache Spark

接下来谈多核机器、 PB级数据和任务,这跟所有从twitter提到的Java或重载机器学习算法类似。谈到Hadoop,不得不说这个应用广泛的框架及它的组 件:Hadoop分布式文件系统(HDFS)、资源管理平台(YARN)、数据处理模块(MapReduce)和其他所需的类库和工具(Common)。 在这些组件上层还有一些其他很受欢迎的可选工具,比如运行在HDFS上的数据库(HBase)、查询语言平台(Pig)和数据仓库基础结构(Hive)。

Apache Spark 作为一种新数据处理模块,以内存性能和快速执行的弹性分布式数据集(RDDs)而出名,不同于不能高效使用内存和磁盘的Hadoop MapReduce。Databricks公布的最新标准显示当用少于10倍节点的时候,对1PB数据的排序Spark比Hadoop快三倍。

典型的Hadoop用例在于查询数据,而Spark正以其快速的机器学习算法越来越出名。但这只是冰山一角,Databricks如是说:“Spark 使应用程序在Hadoop集群中运行在内存中快100倍,当运行在磁盘中时甚至快10倍”。

小结:Spark是在Hadoop生态系统中的后起之秀,有一个常见的误解是我们现在经常谈它一些不合作或竞争的事情,但是我认为我们在这正在看到这个框架的发展。

3、Quasar fibers

我们有机会运行在Hadoop,现在让我们回到单机。事实上,在Java多线程应用程序和集中在单线程上,让我们眼光再长远些。就我们而言,HotSpot JVM线程与本地系统线程相同,持有一个线程并且运行在”虚拟“线程中,这在fibers中都包含的。Java没有原生的fibers支持,但是不要担 心,Quasar通过Parallel Universe解决了我们的问题。

Quasar 是一个开源的JVM库。它支持fibers(也称为轻量级线程),并且还充当框架的角色,在后面中我会提到。在这上下文转换是它本质的名字。当我们核心数 量有限,一旦本地线程数量越大我们就会收到越来越多的上下文开销。一种解决这个问题的方式是fibers,使用单线程支持”多线程“。这看起来像threadcepiton的一个实例。

Fibers还可以被视为一个从线程池的进化,当我们通过应用并行流的时候避开了线程过载的危险。他们更容易衡量线程和允许令人可观的并行”轻量“线程数量。它们不是为了取代线程,而是应该用在那些相对来说经常堵塞的代码中,就如同担任真正异步线程的角色。

小结:并行领域在Java并发性中正提供一种新的思路,虽然还没有版本发布,但是值得一试。

4、Actor和响应式编程

在响应式的官方言论中,最新的释义有4原则:响应、有弹性、灵活性和消息驱动。这基本意味着快速、容错、可伸缩的和支持非阻塞通信。

让我们看看Akka Actor是如果支持它的吧。简单来讲Actor有一个状态和一个特定的行为,通过交换消息沟通彼此的邮箱。一个Actor系统作为一个整体应该被每个应 用程序创建,拥有一个层次结构将任务分解成更小的任务以便每个角色最多只有一个监督的角色。一个角色也可以处理这个任务,通过委托给另一个角色将其进一步 分解或在实例失败的情况下,将它反馈给它的监督者。无论哪种方式,消息不应该包括行为或者共享可变的状态,每个角色都有一个独立的状态和行为。

它是一个从大多数开发者在使用的并发模型的思考模式的转移。尽管它起源于70年代,但是为了适应现代应用程序的要求,直到最近几年它才复苏。并行领域的Quasar也支持Actor,实现的主要区别在于fibers/轻量级线程。

小结:相反的,Actor模型需要管理线程池,让它远离使用工具包。今天面对这种应用程序处理的问题,尤其在我们可以处理拥有更多核心的高并发系统方面又重新有了关注。

总结

关于使用并发或者并行算法,我们今天通过介绍4种方法来解决问题来应对你需要的场景。希望这有 助于激起你的兴趣,以及在这大谈并发话题的现在开拓下你的视野。超越线程池,有一种将这委托给语言及它的工具的趋势——关注新的技术并应用它而不是花费无 数个小时解决竞态条件和锁。


来源:51CTO

相关文章
|
1天前
|
安全 Java 调度
Java线程:深入理解与实战应用
Java线程:深入理解与实战应用
8 0
|
1天前
|
Java
Java中的并发编程:理解和应用线程池
【4月更文挑战第23天】在现代的Java应用程序中,性能和资源的有效利用已经成为了一个重要的考量因素。并发编程是提高应用程序性能的关键手段之一,而线程池则是实现高效并发的重要工具。本文将深入探讨Java中的线程池,包括其基本原理、优势、以及如何在实际开发中有效地使用线程池。我们将通过实例和代码片段,帮助读者理解线程池的概念,并学习如何在Java应用中合理地使用线程池。
|
5天前
|
安全 Java
深入理解 Java 多线程和并发工具类
【4月更文挑战第19天】本文探讨了Java多线程和并发工具类在实现高性能应用程序中的关键作用。通过继承`Thread`或实现`Runnable`创建线程,利用`Executors`管理线程池,以及使用`Semaphore`、`CountDownLatch`和`CyclicBarrier`进行线程同步。保证线程安全、实现线程协作和性能调优(如设置线程池大小、避免不必要同步)是重要环节。理解并恰当运用这些工具能提升程序效率和可靠性。
|
5天前
|
安全 Java
java多线程(一)(火车售票)
java多线程(一)(火车售票)
|
6天前
|
安全 Java 调度
Java并发编程:深入理解线程与锁
【4月更文挑战第18天】本文探讨了Java中的线程和锁机制,包括线程的创建(通过Thread类、Runnable接口或Callable/Future)及其生命周期。Java提供多种锁机制,如`synchronized`关键字、ReentrantLock和ReadWriteLock,以确保并发访问共享资源的安全。此外,文章还介绍了高级并发工具,如Semaphore(控制并发线程数)、CountDownLatch(线程间等待)和CyclicBarrier(同步多个线程)。掌握这些知识对于编写高效、正确的并发程序至关重要。
|
6天前
|
安全 Java 程序员
Java中的多线程并发编程实践
【4月更文挑战第18天】在现代软件开发中,为了提高程序性能和响应速度,经常需要利用多线程技术来实现并发执行。本文将深入探讨Java语言中的多线程机制,包括线程的创建、启动、同步以及线程池的使用等关键技术点。我们将通过具体代码实例,分析多线程编程的优势与挑战,并提出一系列优化策略来确保多线程环境下的程序稳定性和性能。
|
7天前
|
缓存 分布式计算 监控
Java并发编程:深入理解线程池
【4月更文挑战第17天】在Java并发编程中,线程池是一种非常重要的技术,它可以有效地管理和控制线程的执行,提高系统的性能和稳定性。本文将深入探讨Java线程池的工作原理,使用方法以及在实际开发中的应用场景,帮助读者更好地理解和使用Java线程池。
|
7天前
|
存储 安全 Java
Java中的容器,线程安全和线程不安全
Java中的容器,线程安全和线程不安全
15 1
|
7天前
|
Java 开发者
Java中多线程并发控制的实现与优化
【4月更文挑战第17天】 在现代软件开发中,多线程编程已成为提升应用性能和响应能力的关键手段。特别是在Java语言中,由于其平台无关性和强大的运行时环境,多线程技术的应用尤为广泛。本文将深入探讨Java多线程的并发控制机制,包括基本的同步方法、死锁问题以及高级并发工具如java.util.concurrent包的使用。通过分析多线程环境下的竞态条件、资源争夺和线程协调问题,我们提出了一系列实现和优化策略,旨在帮助开发者构建更加健壮、高效的多线程应用。
7 0
|
7天前
|
存储 缓存 监控
Java线程池
Java线程池
46 1