java中的并发和并行之间有区别吗?

Posted

技术标签:

【中文标题】java中的并发和并行之间有区别吗?【英文标题】:Is there a difference between concurrency and parallelism in java? 【发布时间】:2012-12-17 07:19:24 【问题描述】:

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

【问题讨论】:

可能重复:***.com/questions/1897993/… @Cratylus:重复的问题,同样无力的答案,很遗憾。 @TomAnderson:无论如何,请提供一个不弱的答案。 @StriplingWarrior:我试过了,但我的也很虚弱! 【参考方案1】:

这取决于定义它的人。创建 Go 编程语言的人 call code Concurrent 如果将其分解为可以并行处理的部分,而并行意味着这些部分实际上是同时运行的。

由于这些是编程原则,因此编程语言与它们的定义方式无关。但是,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());

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

也很感兴趣:

Concurrency is not Parallelism(演示视频) Concurrency is not Parallelism?(关于 *** 的讨论

【讨论】:

【参考方案2】:

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

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

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

【讨论】:

【参考方案3】:

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

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

【讨论】:

【参考方案4】:

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

也就是说,我解释它们的方式是,如果某件事可以与其他事情同时完成,那么它就是 并发,如果可以完成,那么 并行同时通过多个线程。我主要从JVM garbage collection documentation 中获取这种用法,它说的是

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

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

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

【讨论】:

【参考方案5】:

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

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

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

线程机器上的线程:

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

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

请参考What is the difference between concurrent programming and parallel programming?

【讨论】:

【参考方案6】:

来自 oracle 文档page:

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

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

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

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

更多详情请参考以下帖子:

Parallel programming with threads in Java(Java 特定)

Concurrency vs Parallelism - What is the difference?(与语言无关)

【讨论】:

【参考方案7】:

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

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

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

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


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

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

【讨论】:

【参考方案8】:

问题比较老了,但我想把这两个总结一下,非常简洁明了:

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

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

【讨论】:

以上是关于java中的并发和并行之间有区别吗?的主要内容,如果未能解决你的问题,请参考以下文章

论并行,并发,同步,异步之间的联系与区别

Java虚拟机6:垃圾收集(GC)-2(并行和并发的区别)

Java中并发和并行的概念

多线程并发和并行的区别

并行和并发哪个好?并行和并发的概念和区别

(转)并行与并发的区别