【问题标题】:How are synchronized blocks implemented in Java?Java中的同步块是如何实现的?
【发布时间】:2013-10-08 11:46:14
【问题描述】:

在某些时候线程会竞争监视器,此时一个线程应该获胜,Java 是否使用 CPU 中内置的原子 CAS 操作来实现对这些监视器的获取,如果不是,这是如何工作的?

【问题讨论】:

  • 这是一个虚拟机实现细节。
  • 你不需要实现那个
  • 为什么重要? synchronized 使用确保其目标所需的任何特定于平台的方式提供其并发保证;在根本不支持并发的系统中,或者当 Java 可以证明该方法永远不会被并发访问时,它甚至可以优化为 noop。它们的具体实现方式是您无需担心的实现细节,如果您的 Java 实现不能提供该保证,那么它必须是一个错误或(很少)有文档记录的与标准的偏差。
  • 是的,但我对它的工作原理很感兴趣,原因是当争用高时,同步块优于 java CAS 操作,因为 CAS 在高争用期间使用更多 cpu 时间,但我相信Java 同步必须在 CPU 级别使用 CAS 操作才能正确获取锁,如果这是真的,那么这将产生与在 Java 同步上使用 java CAS 操作相同的问题。
  • 我相信在考虑性能决策时这是一个有趣的问题。

标签: java concurrency synchronization compare-and-swap


【解决方案1】:

我不这么认为,因为在 concurrent 包中,您可以找到在内部使用 CAS 的 Atomic* 类。

另一件事是,这取决于您使用哪种 jvm。因此,以目前的形式,除了告诉您在其他地方使用 CAS 之外,您的问题并不能真正回答。

【讨论】:

    【解决方案2】:

    CAS 是使所有并发在硬件级别工作的原因。如果要跨所有线程更改内存中的一个值,CAS 是最快的方法;任何其他技术也将使用 CAS。因此,对于快速更改,CAS 是要走的路。但是,如果您有 100 个甚至 5 个值要更改,那么使用同步可能会更好。它会做一个 CAS 来锁定监视器,另一个来解锁它,但其余的是正常的内存读取和写入,这比 CAS 快得多。当然,您确实锁定了监视器,这可能会挂起其他线程,减慢您的程序并可能浪费 CPU。

    更令人担忧的是,在 Java 中,任何 CAS(或读/写 volatile 和同步/不同步)都伴随着其他线程的内存视图更新。当您编写 volatile 时,读取它的线程会看到写入线程所做的所有内存更改。这包括将寄存器值转储到内存、刷新缓存、更新缓存以及将数据放回寄存器。但是这些成本与 CAS 平行,因此,如果您已经弄清楚了一个,那么您也已经弄清楚了另一个。

    我认为,从程序员的角度来看,基本思想是对单次读写使用易失性或原子操作,对多次进行同步--如果没有其他 令人信服的理由选择其中之一。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-31
      • 2018-09-18
      • 2017-12-08
      • 1970-01-01
      相关资源
      最近更新 更多