当前位置: 首页 > 科技观察

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

时间:2023-03-21 20:09:34 科技观察

很多人一直在唠叨并发的新概念。然而,许多开发人员还没有机会对其投入太多关注。在本文中,我们将带您了解Java8流、Hadoop、ApacheSpark、Quasar纤程和反应式编程,让您快速入门。特别是如果您不经常使用它们。总之,它并不遥远,就在我们身边。我们如何做到这一点?说到并发,描述手头问题的一个好方法是回答几个小问题以更好地理解它:它是数据处理任务吗?如果是,是否可以分解为一个独立的任务单元?操作系统、虚拟机和您的代码之间的关系是什么?(本机线程与轻量级线程)涉及多少台机器和处理器?(单核vs.多核)一起做题吧,让我们一起为每个问题寻找最佳答案。1、从线程池到并行流在Java8中,我们了解了新的流API接口,它允许应用聚合操作,例如过滤、排序或映射数据流。流允许我们做的另一件事是在多核机器上应用并行操作。ParallelStreams-通过将Fork/Join框架引入Java7来分离线程之间的工作。使用Java6并发库,我们看到ExecutorService创建并处理我们的工作线程池,这不得不说是一种改进。Fork/Join也是建立在ExecutorService之上的。与传统线程的主要区别在于如何在支持多核的线程和机器之间分配工作。使用简单的ExecutorService,您可以完全控制工作线程之间的负载分配,确定该线程要处理的每个任务的大小。而Fork/Join恰好有一个工作窃取算法来在线程之间分配负载。简而言之,这样可以让大的任务被分割成更小的单元,在不同的线程之间进行处理,最后我们可以知道是为了平衡线程之间的工作。然而,这不是灵丹妙药。有时并行流会减慢你的速度,所以你需要考虑一下。在您的方法中使用parallelStream会导致瓶颈和速度减慢(在我们的基准测试中大约慢15%)。假设我们有多个线程在运行,其中一些我们使用parallelStream,在线程池中添加越来越多的线程。这很容易超过我们的核心处理能力,并且由于添加了上下文切换,一切都会变慢。总结:单机并行流抽象线程处理,会在一定程度上平衡核心之间的负载。但是,如果您想有效地使用它们,请记住硬件是关键,而不是产生超过机器处理能力的线程。2、ApacheHadoop和ApacheSpark接下来说多核机器,PB级别的数据和任务,类似于twitter上提到的所有Java或者重载的机器学习算法。说到Hadoop,不得不说这个被广泛使用的框架及其组件:Hadoop分布式文件系统(HDFS)、资源管理平台(YARN)、数据处理模块(MapReduce)以及其他需要的类库和工具(Common)。在这些组件之上分层的是其他流行的可选工具,例如在HDFS(HBase)上运行的数据库、查询语言平台(Pig)和数据仓库基础设施(Hive)。ApacheSpark作为一种新的数据处理模块,以其内存性能和弹性分布式数据集(RDD)的快速执行而著称,这与HadoopMapReduce不能高效利用内存和磁盘不同。Databricks发布的最新基准表明,当使用的节点数量减少10倍时,Spark在排序1PB数据时比Hadoop快三倍。一个典型的Hadoop用例在于查询数据,而Spark因其快速的机器学习算法而越来越出名。但这只是冰山一角,正如Databricks所说:“Spark使应用程序在Hadoop集群上的内存中运行速度提高100倍,在磁盘上运行时速度甚至提高10倍”。简介:Spark是Hadoop生态系统中一颗冉冉升起的新星。有一个普遍的误解,我们现在经常把它说成是既不合作也不竞争的东西,但我认为我们在这里看到了这个框架的发展。3.Quasarfibers我们有机会在Hadoop上运行,现在让我们回到单机。其实,在Java多线程应用中,关注单线程,让我们放眼长远。就我们而言,HotSpotJVM线程与原生系统线程一样,持有一个线程并运行在“虚拟”线程中,这些线程包含在纤程中。Java不支持原生纤程,但不用担心,Quasar使用ParallelUniverse解决了我们的问题。Quasar是一个开源的JVM库。它支持纤程(也称为轻量级线程),同时也充当一个框架,这个我后面会提到。在这种情况下,转换是其本质的名称。当我们的内核数量有限时,一旦本机线程数量增加,我们就会收到越来越多的上下文开销。解决这个问题的一种方法是纤程,使用单线程来支持“多线程”。这看起来像是threadcepiton的一个实例。纤程也可以看作是线程池的演变,因为我们通过应用并行流来避免线程过载的危险。它们更容易通过线程进行扩展,并允许大量并行的“轻型”线程。它们并不是要取代线程,而是应该用在相对经常阻塞的代码中,就好像它们是真正的异步线程一样。简介:并行领域为Java并发提供了一种新的思维方式。虽然目前还没有发布版本,但值得一试。4.Actor与响应式编程在Responsive的官方言论中,最新的解读有4个原则:Responsive、Elastic、Flexible和Message-driven。这基本上意味着快速、容错、可扩展并支持非阻塞通信。看看AkkaActor是否支持。简单的说,Actor有一个状态和一个特定的行为,通过交换消息来与彼此的邮箱进行通信。一个整体的Actor系统应该由每个应用程序创建,层次结构将任务分解为更小的任务,以便每个actor最多有一个监督actor。一个actor也可以通过将其委托给另一个actor来进一步分解它或者在实例失败的情况下将其反馈给它的监督者来处理这个任务。无论哪种方式,消息都不应该包含行为或共享可变状态,每个参与者都有独立的状态和行为。这是大多数开发人员使用的并发模型的思维转变。尽管它起源于70年代,但直到最近几年才复兴以适应现代应用程序的要求。并行领域的Quasar也支持Actor,实现上的主要区别是fibers/lightweightthreads。总结:相比之下,Actor模型需要管理线程池,使其远离工具包。今天面对这个应用程序处理问题,人们重新关注了这一事实,尤其是我们可以处理具有更多内核的高并发系统。总结关于并发或并行算法的使用,今天我们介绍4种解决问题的方法来应对你所需要的场景。希望这有助于激发您的兴趣并在这个伟大的并发讨论时代开阔您的视野。除了线程池之外,还有一种趋势是将其委托给语言及其工具——研究新技术并应用它们,而不是花费无数时间来解决竞争条件和锁。