From af43b7432ac3f6ff08898b7c411377c5ec9ecf18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E9=9B=81=E9=91=AB?= Date: Thu, 19 Mar 2020 20:49:41 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=AF=B9=E7=85=A7=E5=8E=9F=E6=96=87?= =?UTF-8?q?=E5=92=8C=E8=AF=AD=E5=A2=83=EF=BC=8C=E4=BF=AE=E5=A4=8D=E4=BA=86?= =?UTF-8?q?=E6=95=B4=E6=AE=B5=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/24-Concurrent-Programming.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/book/24-Concurrent-Programming.md b/docs/book/24-Concurrent-Programming.md index 0f4d8d74..6f19e1e3 100644 --- a/docs/book/24-Concurrent-Programming.md +++ b/docs/book/24-Concurrent-Programming.md @@ -82,17 +82,17 @@ _并行_ ## 并发的超能力 -想象一下,你是一部科幻电影。你必须在高层建筑中搜索一个精心巧妙地隐藏在建筑物的一千万个房间之一中的单个物品。你进入建筑物并移动走廊。走廊分开了。 +想象一下,你置身于一部科幻电影。你必须在高层建筑中搜索一个精心巧妙地隐藏在建筑物的一千万个房间之一中的单个物品。你进入建筑物并沿着走廊向下移动。走廊分开了。 你自己完成这项任务需要一百个生命周期。 -现在假设你有一个奇怪的超级大国。你可以将自己分开,然后在继续前进的同时将另一半送到另一个走廊。每当你在走廊或楼梯上遇到分隔到下一层时,你都会重复这个分裂的技巧。最后,你会有一个人在整个建筑物的每个终点走廊。 +现在假设你有一个奇怪的超能力。你可以将自己一分为二,然后在继续前进的同时将另一半送到另一个走廊。每当你在走廊或楼梯上遇到分隔到下一层时,你都会重复这个分裂的技巧。最终,整个建筑中的每个走廊的终点都有一个你。 -每个走廊都有一千个房间。你的超级大国正在变得有点瘦,所以你只能让自己50个人同时搜索房间。 +每个走廊都有一千个房间。你的超能力变得有点弱,所以你只能分裂出50个自己来搜索这间房间。 -一旦克隆体进入房间,它必须搜索房间的所有裂缝和隐藏的口袋。它切换到第二个超级大国。它分成了一百万个纳米机器人,每个机器人都会飞到或爬到房间里一些看不见的地方。你不明白这种力量 - 一旦你启动它就会起作用。在他们自己的控制下,纳米机器人开始行动,搜索房间然后回来重新组装成你,突然,不知何故,你只知道物品是否在房间里 +一旦克隆体进入房间,它必须搜索房间的每个角落。这时它切换到了第二种超能力。它分裂成了一百万个纳米机器人,每个机器人都会飞到或爬到房间里一些看不见的地方。你不需要了解这种功能 - 一旦你开启它就会自动工作。在他们自己的控制下,纳米机器人开始行动,搜索房间然后回来重新组装成你,突然间,你获得了寻找的物品是否在房间内的消息。 -我很想能够说,“你在科幻小说中的超级大国?这就是并发性。“每当你有更多的任务要解决时,它就像分裂两个一样简单。问题是我们用来描述这种现象的任何模型最终都是抽象的 +我很想说,“并发就是刚才描述的置身于科幻电影中的超能力“就像你自己可以一分为二然后解决更多的问题一样简单。但是问题在于,我们来描述这种现象的任何模型最终都是泄漏抽象的(leaky abstraction)。 以下是其中一个漏洞:在理想的世界中,每次克隆自己时,你还会复制硬件处理器来运行该克隆。但当然不会发生这种情况 - 你的机器上可能有四个或八个处理器(通常在写入时)。你可能还有更多,并且仍有许多情况只有一个处理器。在抽象的讨论中,物理处理器的分配方式不仅可以泄漏,甚至可以支配你的决策 From 22f2efca612b7c6747b86f7671f1d4816bea1980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E9=9B=81=E9=91=AB?= Date: Thu, 19 Mar 2020 22:38:39 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/24-Concurrent-Programming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/book/24-Concurrent-Programming.md b/docs/book/24-Concurrent-Programming.md index 6f19e1e3..3651e9db 100644 --- a/docs/book/24-Concurrent-Programming.md +++ b/docs/book/24-Concurrent-Programming.md @@ -117,7 +117,7 @@ _并行_ 当“同时”执行的任务相互干扰时,会出现问题。他可以以如此微妙和偶然的方式发生,可能公平地说,并发性“可以说是确定性的,但实际上是非确定性的。”也就是说,你可以假设编写通过维护和代码检查正常工作的并发程序。然而,在实践中,编写仅看起来可行的并发程序更为常见,但是在适当的条件下,将会失败。这些情况可能会发生,或者很少发生,你在测试期间从未看到它们。实际上,编写测试代码通常无法为并发程序生成故障条件。由此产生的失败只会偶尔发生,因此它们以客户投诉的形式出现。 这是推动并发的最强有力的论据之一:如果你忽略它,你可能会被咬。 -因此,并发似乎充满了危险,如果这让你有点害怕,这可能是一件好事。尽管Java 8在并发性方面做出了很大改进,但仍然没有像编译时验证或检查异常那样的安全网来告诉你何时出现错误。通过并发,你可以自己动手,只有知识渊博,可疑和积极,才能用Java编写可靠的并发代码。 +因此,并发似乎充满了危险,如果这让你有点害怕,这可能是一件好事。尽管Java 8在并发性方面做出了很大改进,但仍然没有像编译时验证(compile-time ver)或受检查的异常(checked exceptions)那样的安全网来告诉你何时出现错误。通过并发,你只能依靠自己,只有知识渊博,保持怀疑和积极进取的人,才能用Java编写可靠的并发代码。 From 66b288d389c13f13b85e579569f4f2f8dfc2515f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E9=9B=81=E9=91=AB?= Date: Thu, 19 Mar 2020 22:53:46 +0800 Subject: [PATCH 3/4] =?UTF-8?q?fix=20=E7=BF=BB=E8=AF=91=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/24-Concurrent-Programming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/book/24-Concurrent-Programming.md b/docs/book/24-Concurrent-Programming.md index 3651e9db..6be80e27 100644 --- a/docs/book/24-Concurrent-Programming.md +++ b/docs/book/24-Concurrent-Programming.md @@ -129,7 +129,7 @@ _并行_ 使用多处理器机器,可以在这些处理器之间分配多个任务,这可以显着提高吞吐量。强大的多处理器Web服务器通常就是这种情况,它可以在程序中为CPU分配大量用户请求,每个请求分配一个线程。 -但是,并发性通常可以提高在单个处理器上运行的程序的性能。这听起来像是一个双向的。如果考虑一下,由于上下文切换的成本增加(从一个任务更改为另一个任务),在单个处理器上运行的并发程序实际上应该比程序的所有部分顺序运行具有更多的开销。在表面上,将程序的所有部分作为单个任务运行并节省上下文切换的成本似乎更便宜。 +但是,并发性通常可以提高在单个处理器上运行的程序的性能。这听起来有点违反直觉。如果考虑一下,由于上下文切换的成本增加(从一个任务更改为另一个任务),在单个处理器上运行的并发程序实际上应该比程序的所有部分顺序运行具有更多的开销。在表面上,将程序的所有部分作为单个任务运行并节省上下文切换的成本似乎更便宜。 可以产生影响的问题是阻塞。如果你的程序中的一个任务由于程序控制之外的某些条件(通常是I/O)而无法继续,我们会说任务或线程阻塞(在我们的科幻故事中,克隆体已敲门而且是等待它打开)。如果没有并发性,整个程序就会停止,直到外部条件发生变化。但是,如果使用并发编写程序,则当一个任务被阻止时,程序中的其他任务可以继续执行,因此程序继续向前移动。实际上,从性能的角度来看,在单处理器机器上使用并发是没有意义的,除非其中一个任务可能阻塞。 From 53950246c8ac2f2fc4046412ebdf755cb2e315eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E9=9B=81=E9=91=AB?= Date: Thu, 19 Mar 2020 23:22:17 +0800 Subject: [PATCH 4/4] =?UTF-8?q?fix=20=E5=8D=95=E8=AF=8D=E5=B0=91=E4=BA=86?= =?UTF-8?q?=E4=B8=80=E6=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/24-Concurrent-Programming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/book/24-Concurrent-Programming.md b/docs/book/24-Concurrent-Programming.md index 6be80e27..09f88c73 100644 --- a/docs/book/24-Concurrent-Programming.md +++ b/docs/book/24-Concurrent-Programming.md @@ -117,7 +117,7 @@ _并行_ 当“同时”执行的任务相互干扰时,会出现问题。他可以以如此微妙和偶然的方式发生,可能公平地说,并发性“可以说是确定性的,但实际上是非确定性的。”也就是说,你可以假设编写通过维护和代码检查正常工作的并发程序。然而,在实践中,编写仅看起来可行的并发程序更为常见,但是在适当的条件下,将会失败。这些情况可能会发生,或者很少发生,你在测试期间从未看到它们。实际上,编写测试代码通常无法为并发程序生成故障条件。由此产生的失败只会偶尔发生,因此它们以客户投诉的形式出现。 这是推动并发的最强有力的论据之一:如果你忽略它,你可能会被咬。 -因此,并发似乎充满了危险,如果这让你有点害怕,这可能是一件好事。尽管Java 8在并发性方面做出了很大改进,但仍然没有像编译时验证(compile-time ver)或受检查的异常(checked exceptions)那样的安全网来告诉你何时出现错误。通过并发,你只能依靠自己,只有知识渊博,保持怀疑和积极进取的人,才能用Java编写可靠的并发代码。 +因此,并发似乎充满了危险,如果这让你有点害怕,这可能是一件好事。尽管Java 8在并发性方面做出了很大改进,但仍然没有像编译时验证(compile-time verification)或受检查的异常(checked exceptions)那样的安全网来告诉你何时出现错误。通过并发,你只能依靠自己,只有知识渊博,保持怀疑和积极进取的人,才能用Java编写可靠的并发代码。