|
12 | 12 | >猫咪:“你一定是疯了,否则你就不会来这儿” ——爱丽丝梦游仙境 第6章。
|
13 | 13 |
|
14 | 14 |
|
15 |
| -在本章之前,我们惯用一种简单顺序地叙事方式来编程,有点类似文学中的意识流:第一件事发生了,然后是第二件,第三件……总之,我们完全掌握着事情发生的进展和顺序。如果将值设置为5,再看时它已变成47的话,结果就很匪夷所思了。 |
| 15 | +在本章之前,我们惯用一种简单顺序的叙事方式来编程,有点类似文学中的意识流:第一件事发生了,然后是第二件,第三件……总之,我们完全掌握着事情发生的进展和顺序。如果将值设置为5,再看时它已变成47的话,结果就很匪夷所思了。 |
16 | 16 |
|
17 | 17 | 现在,我们来到了陌生的并发世界。这样的结果一点都不奇怪,因为你原来信赖的一切都不再可靠。它可能有效,也可能无效。更可能得是,它在某些情况下会起作用,而在另一些情况下则不会。只有了解了这些情况,我们才能正确地行事。
|
18 | 18 |
|
|
24 | 24 |
|
25 | 25 | 本章是对并发概念最基本的介绍。虽然我们用到了现代的 Java 8 工具来演示原理,但还远未及全面论述并发。我的目标是为你提供足够的基础知识,使你能够把握问题的复杂性和危险性,从而安全地渡过这片鲨鱼肆虐的困难水域。
|
26 | 26 |
|
27 |
| -更多繁琐和底层的细节,请参阅附录:[并发底层原理](./Appendix-Low-Level-Concurrency.md)。要进一步深入这个领域,你还必须阅读 *Brian Goetz* 等人的 《Java Concurrency in Practice》。在撰写本文时,该书已有十多年的历史了,但它仍包含我们必须了解和明白的知识要点。理想情况下,本章和上述附录是阅读该书的良好前提。另外,*Bill Venner* 的 《Inside the Java Virtual Machine》也很值得一看。它详细描述了 JVM 的内部工作方式,包括线程。 |
| 27 | +更多繁琐和底层的细节,请参阅附录:[并发底层原理](./Appendix-Low-Level-Concurrency.md)。要进一步深入这个领域,你还必须阅读 *Brian Goetz* 等人的 《Java Concurrency in Practice》。在撰写本文时,该书已有十多年的历史了,但它仍包含我们必须要了解和明白的知识要点。理想情况下,本章和上述附录是阅读该书的良好前提。另外,*Bill Venner* 的 《Inside the Java Virtual Machine》也很值得一看。它详细描述了 JVM 的内部工作方式,包括线程。 |
28 | 28 |
|
29 | 29 |
|
30 | 30 | <!-- The Terminology Problem -->
|
31 | 31 |
|
32 | 32 | ## 术语问题
|
33 | 33 |
|
34 |
| -在编程文献中并发、并行、多任务、多处理、多线程、分布式系统(以及可能的其他)使用了许多相互冲突的方式,并且经常被混淆。Brian Goetz在2016年的演讲中指出了这一点[From Concurrent to Parallel](https://www.youtube.com/watch?v=NsDE7E8sIdQ),他提出了一个合理的解释: |
| 34 | +术语“并发”,“并行”,“多任务”,“多处理”,“多线程”,分布式系统(可能还有其他)在整个编程文献中都以多种相互冲突的方式使用,并且经常被混为一谈。 |
| 35 | +*Brian Goetz* 在他 2016 年《从并发到并行》的演讲中指出了这一点,之后提出了合理的二分法: |
35 | 36 |
|
36 | 37 | - 并发是关于正确有效地控制对共享资源的访问。
|
| 38 | + |
37 | 39 | - 并行是使用额外的资源来更快地产生结果。
|
38 | 40 |
|
39 |
| -这些都是很好的定义,但有几十年的混乱产生了反对解决问题的历史。一般来说,当人们使用“并发”这个词时,他们的意思是“一切变得混乱”,事实上,我可能会在很多地方自己陷入这种想法,大多数书籍,包括Brian Goetz的Java Concurrency in Practice,都在标题中使用这个词。 |
| 41 | +这些定义很好,但是我们已有几十年混乱使用和抗拒解决此问题的历史了。一般来说,当人们使用“并发”这个词时,他们的意思是“所有的一切”。事实上,我自己也经常陷入这样的想法。在大多数书籍中,包括 *Brian Goetz* 的 《Java Concurrency in Practice》,都在标题中使用这个词。 |
| 42 | + |
| 43 | +“并发”通常表示:不止一个任务正在执行。而“并行”几乎总是代表:不止一个任务同时执行。现在你能看到问题所在了吗?“并行”也有不止一个任务正在执行的语义在里面。区别就在于细节:究竟是怎么“执行”的。此外,还有一些场景重叠:为并行编写的程序有时在单处理器上运行,而一些并发编程系统可以利用多处理器。 |
| 44 | + |
| 45 | +还有另一种方法,在减速发生的地方写下定义(原文Here’s another approach, writing the definitions around where the |
| 46 | +slowdown occurs): |
40 | 47 |
|
41 |
| -并发通常意味着“不止一个任务正在执行中”,而并行性几乎总是意味着“不止一个任务同时执行。”你可以立即看到这些定义的区别:并行也有不止一个任务“正在进行”。区别在于细节,究竟是如何“执行”发生的。此外,重叠:为并行编写的程序有时可以在单个处理器上运行,而一些并发编程系统可以利用多个处理器。 |
| 48 | +**并发** |
42 | 49 |
|
43 |
| -这是另一种方法,在减速[原文:slowdown]发生的地方写下定义: |
| 50 | +同时完成多任务。无需等待当前任务完成即可执行其他任务。“并发”解决了程序因外部控制而无法进一步执行的阻塞问题。最常见的例子就是 I/O 操作,任务必须等待数据输入(在一些例子中也称阻塞)。这个问题常见于 I/O 密集型任务。 |
44 | 51 |
|
45 |
| -_并发_ |
| 52 | +**并行** |
46 | 53 |
|
47 |
| -同时完成多个任务。在开始处理其他任务之前,当前任务不需要完成。并发解决了阻塞发生的问题。当任务无法进一步执行,直到外部环境发生变化时才会继续执行。最常见的例子是I/O,其中任务必须等待一些input(在这种情况下会被阻止)。这个问题产生在I/O密集型。 |
| 54 | +同时在多个位置完成多任务。这解决了所谓的 CPU 密集型问题:将程序分为多部分,在多个处理器上同时处理不同部分来加快程序执行效率。 |
48 | 55 |
|
49 |
| -_并行_ |
| 56 | +上面的定义告诉了我们术语令人困惑的原因:两者的核心是“同时完成多个任务”。并行增加了跨多个处理器的分布。更重要的是,这两种方法可以解决不同类型的问题:解决I / O绑定问题和并行化可能对您没有任何好处,因为该问题不是整体速度,而是阻塞。采取计算约束问题并尝试在单个处理器上使用并发性解决问题可能会浪费时间。两种方法都试图在更短的时间内完成更多工作,但是它们实现加速的方式却有所不同,并且取决于问题所施加的约束。 |
50 | 57 |
|
51 |
| -同时在多个地方完成多个任务。这解决了所谓的计算密集型问题,如果将程序分成多个部分并在不同的处理器上编辑不同的部分,程序可以运行得更快。 |
52 | 58 |
|
53 | 59 | 术语混淆的原因在上面的定义中显示:其中核心是“在同一时间完成多个任务。”并行性通过多个处理器增加分布。更重要的是,两者解决了不同类型的问题:解决I/O密集型问题,并行化可能对你没有任何好处,因为问题不是整体速度,而是阻塞。并且考虑到计算力限制问题并试图在单个处理器上使用并发来解决它可能会浪费时间。两种方法都试图在更短的时间内完成更多,但它们实现加速的方式是不同的,并且取决于问题所带来的约束。
|
54 | 60 |
|
|
0 commit comments