【问题标题】:Synchronized Vs Semaphore同步与信号量
【发布时间】:2013-05-30 06:26:07
【问题描述】:

在阅读Java并发时,我有以下疑问:

  1. Java 是否提供较低级别的构造,然后进行同步以进行同步?

  2. 在什么情况下我们会使用信号量而不是同步(在 Java 中提供监控行为)

【问题讨论】:

  • 我认为对于问题 1,我们可以使用 ReentrantLock 和 Condition 对象,它们是一种较低级别的构造..

标签: java semaphore monitor synchronized


【解决方案1】:

同步只允许一个执行线程同时访问资源。信号量最多允许 n(您可以选择 n 个)执行线程同时访问资源。

【讨论】:

    【解决方案2】:
    1. 还有volatile关键字,根据http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.htmlvolatile变量访问比通过同步代码访问这些变量效率更高

    2. java.util.concurrent.Semaphore 用于限制可以访问资源的线程数。也就是说,synchronized 只允许一个线程获取锁并执行同步块/方法,而 Semaphore 最多允许 n 个线程去并阻止其他线程。

    【讨论】:

    • synchronized 提供了线程干扰和内存一致性错误的解决方案,但是 volatile 只提供了内存一致性错误的解决方案,所以我们不能使用 volatile 来提供操作中的原子性,是我在这里遗漏了什么吗?
    • volatile 还提供对 long / double 的原子访问
    • 使用 volatile 你可能仍然有脏读并破坏你的共享值。所以它不是同步的替代品。
    【解决方案3】:

    还有atomics。这可以访问作为所有同步基础的基本硬件比较和交换命令。例如,它允许您安全地增加一个数字。如果您++ 一个易失性字段,则执行相同指令的另一个线程可以在您的线程写入该字段之前读取该字段,然后在您的线程之后写回它。所以一个增量会丢失。 Atomics 以“原子方式”进行读写操作,从而避免了这个问题。

    实际上,volatile、同步语句、原子倾向于强制所有线程数据从主内存刷新和/或酌情写入主内存,因此它们都不是真正的 这么低的水平。 (我在这里简化一下。与 C# 不同,Java 并没有真正的“主存”概念。)

    【讨论】:

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