35

我一直在谷歌做一些研究,并不能完全理解 Java 中并发和并行程序之间的差异(如果有的话)。我看过的一些信息表明两者之间没有区别。是这样吗??

4

8 回答 8

21

这取决于定义它的人。创建 Go 编程语言的人调用代码 Concurrent如果它被分解成可以并行处理的部分,而 Parallelism 意味着这些部分实际上是同时运行的。

由于这些是编程原则,因此编程语言与它们的定义方式无关。但是,Java 8 将具有更多功能来支持并发和并行性,而不会过多地弄乱您的代码。例如,像这样的代码:

List<Integer> coolItemIds = new List<Integer>();
for(Item item : getItems())
{
    if(item.isCool())
    {
        int itemId = item.getId();
        coolItemIds.add(item);
    }
}

...这是非并发和非并行的,可以这样写(我的语法可能是错误的,但希望你明白):

Iterable<Item> items = getItems();
Iterable<Item> coolItems = items.filter(item -> item.isCool());
Iterable<Integer> coolItemIds = coolItems.map(item -> item.getId());

上面的代码是以并发的方式编写的:没有一个给定的代码要求一次过滤一个coolItems,或者一次只能调用getId()一个项目,甚至是列表开头的项目需要在最后的项目之前进行过滤或映射。根据Iterable返回的类型getItems(),给定的操作可能会或可能不会并行运行,但您编写的代码是并发的。

还有兴趣:

于 2013-01-02T22:32:57.883 回答
17

我想这取决于你的定义,但我的理解大致是这样的:

  • 并发是指以某种未指定的顺序发生的事情。多任务处理——通过时间片交错指令来执行多个程序——是考虑这种并发性的好方法。
  • 并行性(或“真正的”并行性)指的是在字面上同时发生的事情。这需要硬件支持(协处理器、多核处理器、联网机器等)。所有并行性都是并发的,但并非所有并发性都是并行的。

据我所知,这两个术语都不是 Java 特定的,也没有任何 Java 特定的细微差别。

于 2013-01-02T22:33:56.020 回答
5

并行化(或并行或并行计算)是一种计算形式,其中许多计算同时进行。本质上,如果一个 CPU 密集型问题可以划分为较小的独立任务,那么这些任务可以分配给不同的处理器

并发更多的是关于多任务处理,它执行许多操作,但不是必要的 CPU 密集型问题。

于 2013-01-02T22:37:45.487 回答
3

我认为这两个术语没有明确定义的不同含义。它们都是艺术术语而不是技术术语。

也就是说,我解释它们的方式是,如果某件事可以与其他事情同时完成,那么它就是并发的,如果它可以由多个线程同时完成,那么它就是并行的。我主要从JVM 垃圾收集文档中获取这种用法,其中说类似

并发标记清除收集器,也称为并发收集器或 CMS,针对对垃圾收集暂停敏感的应用程序。它同时执行大多数垃圾收集活动,即在应用程序线程运行时

CMS 收集器现在使用多个线程在具有多个处理器的平台上并行执行并发标记任务。

诚然,这是一个非常具体的背景,从中概括可能是不明智的。

于 2013-01-02T23:48:51.483 回答
2

如果您使用线程进行编程(并发编程),则不一定会这样执行(并行执行),因为这取决于机器是否可以处理多个线程。

这是一个视觉示例。非线程机器上的线程:

         --  --  --
      /              \
 >---- --  --  --  -- ---->>

线程机器上的线程:

       ------
      /      \
  >-------------->>

破折号代表执行的代码。如您所见,它们都分开并单独执行,但线程机器可以一次执行多个单独的部分。

请参考这篇并发编程和并行编程有什么区别?

于 2015-04-22T12:55:24.817 回答
2

从 oracle 文档页面

单个处理器上的多线程进程中,处理器可以在线程之间切换执行资源,从而实现并发执行

共享内存多处理器环境中的同一个多线程进程中,进程中的每个线程可以同时运行在单独的处理器上,从而实现并行执行

当进程的线程数与处理器数一样少或多时,线程支持系统与操作环境一起确保每个线程在不同的处理器上运行。

Java SE 7 通过添加ForkJoinPool API进一步增强了并行处理。

有关更多详细信息,请参阅以下帖子:

使用 Java 中的线程进行并行编程 (特定于 Java)

并发与并行 - 有什么区别?(语言不可知)

于 2017-07-04T16:22:50.217 回答
1

并发是一种架构设计模式,它允许您一次运行多个操作(可以但不必并行执行)。

在此类操作的单核执行的情况下,可以通过例如上下文切换来“模拟”并行化(假设您的编程语言使用线程进行并行执行)。

假设您有两个线程,在一个线程中将作业排入队列。第二个等待,直到任何作业存在并拿起它执行。尽管使用单核处理器,但它们都在运行和通信(通过队列)。

这是一个并发执行——即使线程在单个核心上顺序执行(共享它)。


同一练习的并行版本看起来很相似,但有一个区别:

线程的执行将发生在多核处理器上。线程将彼此并行运行,而不是按顺序运行(每个线程都在自己的核心上)。

于 2018-12-04T20:42:30.433 回答
0

问题很老了,但我想以非常简洁明了的方式总结这两个:

  1. 并发-考虑一个参与者的多任务处理:
    当 x 个进程/线程 (x>1) 竞争相同的资源时。在并发的情况下,当两个进程/线程在一个 CPU 上执行时,它们并不是真正并行的,这意味着 CPU 时钟将以超快的方式在进程之间来回切换,这将描绘出一种错觉并行性,但同样 - 它是不同进程/线程之间共享的 1 个 CPU。想象一下要执行 5 条指令,它们竞争 CPU 的资源,以便得到执行;

  2. 并行性-考虑多个任务,其中每个任务由单独的参与者处理:
    当 x 个进程/线程 (x>1) 同时并行执行时。想象一下如果有 5 个进程/线程,并且有 5 个 CPU 核心,这意味着每个核心可以独立执行每个线程/进程。

于 2020-06-21T11:46:53.243 回答