【问题标题】:Is Java Memory Model still in use?Java 内存模型还在使用吗?
【发布时间】:2016-03-09 20:06:48
【问题描述】:

它根据 Java 并发原语解释并发,但实际上性能最佳的并发代码使用 sun.misc.Unsafe 原语,其中涉及 CAS 和直接内存栅栏指令。

此外,我个人更喜欢在对并发代码进行推理时使用栅栏而不是发生之前。

那么,JMM 对于现代 Java 仍然有效吗?

或者,换句话说,可以使用 JMM 对程序进行推理,通过 sun.misc.Unsafe 方法同步吗?

【问题讨论】:

  • 是的。在绝大多数情况下,您不应该使用Unsafe,因为它不安全。
  • JMM 旨在始终有效,而不仅仅是在绝大多数时间。
  • 我一直在编写 Java 代码……就像从 Java 的第一天开始一样。我从未使用过 sun.misc.Unsafe。是什么让您认为“高质量”并发代码需要它?!我想说,恰恰相反:高质量的代码应该专注于健壮的高级抽象......
  • @Jägermeister 许多 java.util.concurrent 类以及现代框架都使用它。在这里查看详细信息,例如:docs.google.com/document/d/…
  • 是的,但这有关系吗?从某种意义上说:我为什么要关心如何实现高级构造?只要我没有遇到这个实现对于我的用例来说“不够好”的麻烦。此外:您的问题基本上是要求“基于意见”的答案。而这样的问题在这里不受欢迎。

标签: java concurrency java-memory-model


【解决方案1】:

那么,JMM 对于现代 Java 仍然有用吗?

不是真的。

那么,JMM 对于现代 Java 仍然有效吗?

是的,仍然有效

大部分 java 内存都在后台处理,垃圾回收调用和手动内存操作很少使用,被认为是糟糕的设计。大多数人会告诉你它仍然有用,因为可以完成某些事情,例如本机内存分配或创建本机并发。

虽然 JMM 受支持且有效,但没有人真正使用它。为什么?使用 sun.misc.Unsafe 来完成这些类型的事情是不安全的。它是不安全代码的一个原因是实例永远不会被垃圾收集。 (除非这是你想要的)。就像为线程使用 volatile 变量一样;它从未在本地缓存过,并且会降低性能并且难以编写。在非原子操作中可能会给你不同的结果!

使用栅栏代码并没有错,但要考虑权衡。问问自己为什么使用 java 而不是 C?

简而言之,完成某些事情可能很有用,但它不切实际,因为有其他方法可以做到这一点。 (本机代码)


对于文斯的评论,我将添加以下内容:

volatile int i = 0;

public void foo() { 
    if (i == 0) i = i + 1;
}

上面的代码本质上是不安全的,尽管变量的声明为 volatile 意味着读写被刷新到主内存 - 这种方法的唯一安全实现是这样的:

int i = 0;

public synchronized void foo() {
    if (i == 0) 
    i = i + 1;
}

那么你应该更喜欢哪个?好吧,如果您有多个线程根据该字段的值修改一个字段(即比较和设置),那么同步是唯一安全的解决方案。

【讨论】:

  • JMM 是 Java 内存模型,在 JLS 的 17.4 部分中进行了描述,用于对并发代码进行推理。我不明白你的回答:-(
  • 就像我说的,这取决于您使用它的目的。如果您将它用于线程,则没有用,因为您可以创建同步块来防止竞争条件,而不是使用 volatile 检查变量。但是要像您在标题中描述的那样使用 sun.misc.Unsafe 。不,它不实用,也不会收集垃圾。如果您要操作内存,则需要编写困难的代码来处理特定情况。
  • 啊。但我的问题是关于 JMM 对通过 Unsafe 方法同步的并发程序进行推理的适用性。
  • 例如:同步块几乎可以替代 volatile 同步订单。如果您查看任何具有 99.9% 时间的多线程的行业代码,您将不会发现人们在变量上使用 volatile 来检查线程安全性。 JMM 已被许多替代方案所取代。
  • @user3659052 您是否建议应该使用同步块来代替 volatile 的使用?如果是这样,我认为您应该研究差异,因为它们不可互换。如果不是,您是什么意思“替换 volatile 同步订单”?据我所知,volatile 确保数据存储在主内存中,允许所有线程查看相同的副本(而不是本地存储)。
猜你喜欢
  • 2011-06-03
  • 2013-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-28
  • 2019-04-06
相关资源
最近更新 更多