为什么线程共享堆空间?

每个线程都有自己的堆栈,但它们共享一个公共堆。

每个人都很清楚,堆栈是用于局部/方法变量的,堆是用于实例/类变量的。

在线程之间共享堆有什么好处。

有多个线程同时运行,因此共享内存可能会导致并发修改、互斥等开销等问题。堆中的线程共享哪些内容。

为什么会这样?为什么不让每个线程也拥有自己的堆呢?任何人都可以提供一个真实世界的例子,线程如何利用共享内存?


答案 1

当您想要将数据从一个线程传递到另一个线程时,您会怎么做?(如果你从来没有这样做过,你就会编写单独的程序,而不是一个多线程程序。有两种主要方法:

  • 您似乎认为理所当然的方法是共享内存:除了具有令人信服的原因的数据(例如堆栈)之外,所有线程都可以访问所有数据。基本上,有一个共享堆。这给了你速度:每当一个线程更改某些数据时,其他线程都可以看到它。(限制:如果线程在不同的处理器上执行,则情况并非如此:程序员需要特别努力地工作才能正确有效地使用共享内存。大多数主要的命令式语言,特别是Java和C#,都喜欢这种模型。

    每个线程可以有一个堆,外加一个共享堆。这需要程序员决定将哪些数据放在哪里,而这通常与现有的编程语言不能很好地融合。

  • 双重方法是消息传递:每个线程都有自己的数据空间;当一个线程想要与另一个线程通信时,它需要显式地将消息发送到另一个线程,以便将数据从发送方的堆复制到接收方的堆中。在这种情况下,许多社区更喜欢调用线程进程。这给了你安全:由于线程不能随心所欲地覆盖其他线程的内存,因此可以避免很多错误。另一个好处是分发:您可以使线程在单独的计算机上运行,而不必更改程序中的一行。您可以找到大多数语言的消息传递库,但集成往往不太好。理解消息传递的好语言是ErlangJoCaml

    事实上,消息传递环境通常在幕后使用共享内存,至少只要线程在同一台机器/处理器上运行即可。这节省了大量的时间和内存,因为将消息从一个线程传递到另一个线程,然后不需要创建数据的副本。但是,由于共享内存不向程序员公开,因此其固有的复杂性仅限于语言/库实现。


答案 2

因为否则它们将是过程。这就是线程的整个概念,共享内存。


推荐