【问题标题】:is Clojure Refs/do-sync just the equivalent of java "synchronized" block?Clojure Refs/do-sync 是否等同于 java“同步”块?
【发布时间】:2013-04-17 19:22:41
【问题描述】:

我试图说服自己,对于并发编程来说,clojure 确实比 java 更容易。

但我觉得 Clojure Refs/do-sync 和 java 的“同步”块几乎一模一样。然后我读了这个帖子:Clojure STM ( dosync ) x Java synchronize block

---我正在重新启动一个新线程,因为如果我在旧线程中发表评论,由于年龄较大,响应可能不高。

Michał Marczyk 在该线程中的第一条评论声称不同之处在于 java 同步块使用锁而 Clojure 使用事务。我认为这种说法并没有触及问题的本质:在底层,事务仍然是通过锁来实现的。所以“java 使用锁”并不是 Clojure 更好的原因。

我认为真正的好处是 Clojure 事务管理自动锁,就像 DB 事务一样。这样,获取锁的顺序和执行事务的顺序由事务管理器决定,程序员不需要关心这些,而在java世界中,程序员必须显式选择使用哪个锁同步块,这会导致可能的死锁。例如,事务管理器可以使用两阶段锁定来避免死锁。

上面说的有道理吗?

谢谢 杨

【问题讨论】:

    标签: concurrency clojure transactions stm


    【解决方案1】:

    Clojure 中的 Ref 是一种不同的并发抽象,它像数据库事务一样工作 - 它具有原子性、一致性和隔离性属性。它建立在 JVM 锁定机制之上,因此可以用 Java 自己实现。我们不这样做的原因是类似 Ref 的机制需要预先实现其他非平凡的机制:

    【讨论】:

    • 对此+1。还要添加我自己的答案,因为问题明确指出了我的旧答案,并且我想做一些额外的 cmets。
    【解决方案2】:

    此处引用答案的作者 -- 让我尝试详细说明:

    实际上,在引用的答案中,我首先声称“dosyncsynchronized 可以访问完全不同的并发抽象”。此外,我将synchronized 描述为不仅仅是“使用锁”,而是“一种获取和释放锁的方式”。

    换句话说,虽然 STM 确实在后台使用了锁,但它暴露了可以这样推理的事务语义;例如,它通过构造没有死锁(然而,活锁是可能的)。相比之下,synchronized 只是程序员明确声明在大括号标记的点处获取和释放某某对象的监视器的一种方式。这里的重要区别在于语义,而不是实现。

    此外,STM 不仅仅管理锁定顺序;有 MVCC,正如 Grzegorz 所提到的,有自动重启事务,有 ensurecommute(如果你愿意的话,可以控制一致性与并发性的权衡),还有 STM 和代理之间的合作(代理操作放入队列send 仅在从事务中调用时才会在提交时分派)。

    所以,STM 确实是一种管理锁的机制,这样描述它是有用的;但更大的图景是 STM 实现使用它需要的任何内部细节,包括锁,为程序员提供另一种并发抽象,合理地无泄漏,如果要从中提取全部好处,最终必须这样处理它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-04
      • 1970-01-01
      • 1970-01-01
      • 2016-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-25
      相关资源
      最近更新 更多