使用挥发性变量和信号量-Java



我是从线程,信号量,挥发性变量等开始的。我想知道当我使用信号量时是否有必要将变量定义为挥发性,我的意思是:

有2个线程,一个增加,另一个会减小变量,显然,在每个访问之前,我都有一个在任何时候控制一个线程的utex,一个线程是用变量"播放"的。

有必要定义为挥发性?

来自信号的API DOC:

内存一致性效果:在调用一个线程中的操作"释放"诸如 release() 之类的方法发生在之前的操作之后成功的"获取"诸如另一线程中的acquire()之类的方法。

因此,可以安全地读取/写由信号量保护的变量。无需将它们声明为volatile

信号量不应在同步的位置使用,因为信号量也不容纳独特的相互锁定,即使将其初始化为一个,例如在某些对象上同步。的确,定位为1的信号量,一次只允许一个线程访问对象,该对象容纳许可证。但是保留许可证的线程不拥有它,任何其他线程都可以释放并获得许可证。因此,两个线程可以同时访问同一对象,如果两个线程都操纵该对象,则会出现多线程问题,例如丢失更新,陈旧读取等。

在您的示例中有2个线程,一个增加,一个降低相同的变量。相互排斥是足够的,不需要挥发性声明。在这里,我认为相互排除是通过同步而不是通过信号量实现的。

挥发性不如同步不严格,当执行的操作是原子(读或写)时,您可能需要使用挥发性。当执行读取式 - Write 操作时,不应使用挥发性。

我想知道当我使用信号量时是否有必要定义 可变为挥发性,

我认为没有任何限制。Mutex是一个相互排除的信号量,它是信号量的特殊变体,一次只允许一个储物柜。它等同于一个正常计数信号量,计数为1,并且要求它只能由锁定它的同一线程释放。

如果我们在Java 中专门针对信号量的strong>:Semaphore是允许的计数器,而获取就像减少,而不是等待而不是低于零以下。它没有上限。如CIP中所述:

实现没有实际许可证对象,信号量确实 没有将许可证与线程分配许可证,因此获得了许可证 一个线程可以从另一个线程释放。你可以想到 作为消耗许可证并释放作为创建许可证;A 信号量不仅限于其创建的许可证数量。

对于您的方案,您可以共享一个计数器并使其波动或更好地使用AtomicInteger,因为它们使用CAS机制在低竞争下表现良好。

最新更新