Java中并发和并行有什么区别吗?

35

我正在Google上做一些研究,但是无法完全理解Java中并发程序和并行程序之间的差异(如果有的话)。我查看的一些信息表明两者之间没有区别。这是真的吗?


可能是重复的问题:https://dev59.com/gXI-5IYBdhLWcg3wW2-p - Cratylus
2
@Cratylus:重复的问题,同样无力的答案,可悲啊。 - Tom Anderson
2
@TomAnderson:尽管放手去贡献一个不弱的答案。 - StriplingWarrior
2
@StriplingWarrior:我也试了一下,但我的也很弱! - Tom Anderson
8个回答

21
这取决于定义它的人。创建Go编程语言的人认为,如果将其分解成可以并行处理的部分,则call code 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(),甚至不需要在列表开头的项目被过滤或映射之前就处理列表末尾的项目。根据从getItems()返回的Iterable类型,给定的操作可能会或可能不会并行运行,但你编写的代码是并发的。
另外值得注意的是:

17

我认为这取决于你的定义,但我的理解大致如下:

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

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


5

并行化(或并行计算)是一种计算方式,许多计算可以同时进行。本质上,如果一个消耗大量 CPU 的问题可以被分解成更小的独立任务,那么这些任务可以被分配给不同的处理器。

并发性 更多的是关于多任务处理,即执行许多操作但不一定是消耗大量 CPU 的问题。


3
我认为这两个术语没有明确定义的不同含义。它们都是艺术术语,而不是技术术语。
话虽如此,我的理解是,如果某物可以与其他事物同时完成,则其为“并发”,如果可以由多个线程同时完成,则其为“并行”。我主要从JVM垃圾回收文档中获取此用法,其中说到:
“并发标记扫描收集器(concurrent mark sweep collector),也称为并发收集器或CMS,针对对垃圾回收暂停敏感的应用程序。它大部分垃圾回收活动是并发完成的,即在应用程序线程运行时完成。”

“CMS收集器现在在具有多个处理器的平台上使用多个线程并行执行并发标记任务。”
不可否认,这是一个非常特定的上下文,从中推广可能是不明智的。

2
如果你使用线程编程(并发编程),不一定会执行为并行执行,因为这取决于机器是否能够处理多个线程。
下面是一个视觉化的例子。非线程化机器上的线程:
         --  --  --
      /              \
 >---- --  --  --  -- ---->>

在多线程的机器上运行的线程:

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

这些短横线代表已执行的代码。您可以看到,它们都被分开并单独执行,但是线程化机器可以同时执行几个独立的部分。

请参考此什么是并发编程和并行编程之间的区别?


2
从Oracle文档页面
在单处理器的多线程进程中,处理器可以在线程之间切换执行资源,导致并发执行
在同一共享内存多处理器环境的多线程进程中,该进程中的每个线程可以同时在不同的处理器上运行,导致并行执行
当进程的线程数少于或等于处理器数时,线程支持系统与操作环境确保每个线程在不同的处理器上运行。
Java SE 7通过添加ForkJoinPool API进一步增强了并行处理。
有关更多详细信息,请参阅以下文章: 使用Java的线程进行并行编程(仅限Java) 并发与并行-有什么区别?(语言无关)

1

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

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

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

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


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

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


0

这个问题很老了,但我想用非常清晰简洁的方式总结这两个概念:

  1. 并发 - 可以将其视为单个参与者的多任务处理:
    当x个进程/线程(x>1)竞争同一资源时,就会出现并发。在并发情况下,当两个进程/线程在一个CPU上执行时,它们实际上并不是并行的,也就是说,CPU时钟会以超快的速度在进程/线程之间来回切换,从而产生并行的假象,但实际上它们共享同一个CPU。想象一下有5条指令需要执行,并且它们竞争获取CPU资源以便执行;

  2. 并行 - 可以将其视为由多个参与者独立完成的多个任务:
    当x个进程/线程(x>1)同时执行时,就会出现并行。想象一下有5个进程/线程和5个CPU核心,这意味着每个核心可以独立地执行每个线程/进程。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接