如何在java中进行多处理,以及期望的速度提升?

我是一个使用Java在csv文件上进行数据处理的新手。 为此,我使用Java(线程池)的multithreadingfunction将csv文件批量导入Java,并在每个行上执行一些操作。 在我的四核上,multithreading可以大大加快这个过程。

我很想知道多处理如何/更加加速操作? 如果是这样,是否有可用的教程? (Java Basic Tutorial提到了一个类,但是我不熟悉语法来自己理解这个类:

来自http://download.oracle.com/javase/tutorial/essential/concurrency/procthread.html :

Java虚拟机的大多数实现都作为单个进程运行。 Java应用程序可以使用ProcessBuilder对象创建其他进程。 多进程应用程序超出了本课程的范围[他们在哪里解释?]

我很想知道多处理如何/更加加速操作?

不,实际上它可能会使情况变得更糟。 如果您要从multithreading切换到多处理,那么您将多次有效地启动JVM。 启动JVM并非易事。 实际上,桌面计算机上的JVM启动方式与企业公司启动JVM的方式不同,只是为了减少小程序为典型最终用户启动的等待时间。

每个开发人员都应该对Amdahl定律有所了解,以了解多处理如何根据给定条件加速。

Amdahl定律是算法的并行化实现相对于串行算法的预期加速之间的关系的模型,假设在并行化时问题大小保持不变。

这是一个很好的解读:阿姆达尔定律

阿姆达尔定律

增益取决于映射/减少数据所需的时间。

例如,如果文件在多台机器上加载开始(想象它就像分片文件系统一样),那么获取数据就没有延迟了。 如果数据来自单个位置,则受该机制的限制。

然后必须组合/聚合数据 – 不知道更多,不可能猜测。 如果所有处理都依赖于拥有所有数据,那么与最终结果可以独立计算相比,它的命中率更高。

你有非常少量的非常小的文件:除非你所做的是计算上昂贵的,否则我怀疑这是值得的,但很难说。 假设没有网络/磁盘瓶颈,您将获得( 非常 )线性加速,并使用delta来聚合结果。 真正的加速/增量取决于我们目前不太了解的一系列因素。

OTOH,你可以设置一个小的Hadoop设置,然后尝试一下,看看会发生什么。

检查JVM上的文档以查看它是否支持multithreading。 太确定太阳了。 Java Concurrency In Practice是multithreading的起点。

您问题的第一部分是:从性能角度来看,multithreading是否优于multithreading? 在具有强大multithreading支持的系统中,从性能角度来看,线程应始终优于进程。 线程之间存在更多隔离(没有共享内存,除非通过IPC机制明确设置),因此您可能希望采用多进程路由来防止危险线程相互踩踏。

对于数据处理,线程应该是最好的方法。 如果本地计算机上的线程不够,我将跳过多进程解决方案,直接进入像Hadoop这样的map-reduce系统。

至于为什么提到多进程应用程序,我认为作者希望完整。 虽然未提供教程,但指向其他文档的链接是。 使用多处理的最大缺点是您必须处理进程间通信。 与线程不同,你不能只是分享一些内存并在它周围抛出一些互斥量并称之为一天。


从评论中可以看出,对于“多处理”实际上存在一些混淆。 线程是必须由代码创建的构造。 有用于创建和管理线程的API。 但是,可以在命令行上手动创建进程。 在unix框中执行以下操作以运行foo四个实例(进程)。 请注意,最后的&是必需的。

 $ ./foo & ./foo & ./foo & ./foo & 

现在,如果你有一个输入文件,foo需要处理的bar ,使用像split这样的东西split它分成四个相等的段,并在其上运行foo

 $ ./foo bar.0 > bar.0.out & ./foo bar.1 > bar.1.out & ./foo bar.2 > bar.2.out & ./foo bar.3 > bar.3.out & 

最后,您需要组合bar.?.out文件。 运行这样的测试应该会让您对使用重量级过程是否适合您的应用程序有所了解。 如果您已经构建了一个multithreading应用程序,那可能就好了。 但随意进行一些实验,看看过程是否更好。 一旦确定流程是可行的方法,请重新组织代码以使用ProcessBuilder自行启动流程。

对于许多用例,在比较产生线程与产生进程以及比较线程之间的通信与进程间通信时,multithreading比多处理具有更少的开销。

但是, 在某些情况下,multithreading会降低性能,使单个线程的性能优于多个线程 ,例如严重受错误共享影响的情况。 使用多处理,由于每个进程都有自己的内存空间,因此不会发生错误共享,并且多处理解决方案可以胜过multithreading解决方案。

总的来说,在选择并发编程解决方案时应该进行一些分析,因为性能最佳的解决方案可能因具体情况而异。 不能假设multithreading优于多处理,因为存在multithreading执行比单线程更差的反直觉情况。 当性能是一个主要考虑因素时,运行基准来比较单线程单进程与multithreading与多处理解决方案,以确保您真正获得预期的性能优势。

简而言之,在选择解决方案时,还有其他考虑因素。

有几种方法可以在Java中启动新进程:

  1. ProcessBuilder.start()
  2. Runtime.exec()适用于ProcessBuilder
  3. 运行Runtime.exec() Apache Commons Exec

使用ProcessBuilder

 ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2"); Map env = pb.environment(); env.put("VAR1", "myValue"); env.remove("OTHERVAR"); env.put("VAR2", env.get("VAR1") + "suffix"); pb.directory(new File("myDir")); File log = new File("log"); pb.redirectErrorStream(true); pb.redirectOutput(Redirect.appendTo(log)); Process p = pb.start(); assert pb.redirectInput() == Redirect.PIPE; assert pb.redirectOutput().file() == log; assert p.getInputStream().read() == -1; 

使用Runtime

 Runtime r = Runtime.getRuntime(); Process p = r.exec("firefox"); p.waitFor(10, TimeUnit.SECONDS); p.destroy(); 

使用Apache Commons Exec:

 String line = "AcroRd32.exe /p /h " + file.getAbsolutePath(); CommandLine cmdLine = CommandLine.parse(line); DefaultExecutor executor = new DefaultExecutor(); int exitValue = executor.execute(cmdLine); 

多处理和multithreading之间的主要区别来自:

  • 多处理和multithreading之间的关键区别在于多处理允许系统将两个以上的CPU添加到系统中,而multithreading允许一个进程生成多个线程以提高系统的计算速度。
  • 多处理系统同时执行多个进程,而multithreading系统允许同时执行进程的多个线程。
  • 创建进程会消耗时间甚至耗尽系统资源。 但是,创建线程是经济的,因为属于同一进程的线程共享该进程的所有权。
  • 多处理可以分为对称多处理和非对称多处理,而multithreading不进一步分类。

其他链接: