使用volatile变量和信号量 - Java

时间:2015-05-09 15:16:01

标签: java multithreading mutex semaphore volatile

我从Threads,Semaphores,volatile变量等开始。 我想知道当我使用信号量时,有必要将变量定义为volatile,我的意思是:

有2个线程,一个增加,另一个减少变量,例如,显然,在每次访问之前,我有一个互斥量,任何时候控制只有一个线程“正在”变量。

有必要定义为volatile?

3 个答案:

答案 0 :(得分:3)

来自Semaphore的API文档:

  

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

因此,读取/写入由信号量保护的变量是安全的。

答案 1 :(得分:2)

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

在你有两个线程的例子中,一个增加,一个减少同一个变量。相互排斥是充分的,不需要挥发性声明。在这里,我假设互斥是通过同步而不是通过信号量实现的。

volatile不比synchronized更严格,当执行的操作是原子(读或写)时,您可能希望使用volatile。执行读取 - 更新 - 写入操作时不应使用volatile。

答案 2 :(得分:1)

  

我想知道当我使用信号量时,有必要定义   变量为volatile,

我认为没有任何此类限制。互斥量是互斥信号量,是信号量的特殊变体,一次只允许一个锁定器。它相当于一个计数为1的正常计数信号量,并且要求它只能被锁定它的同一个线程释放。

如果我们专门针对Java中的Semaphore谈论 :信号量是许可证的计数器,并且获取就像是等待而不是低于零的递减。它没有上限。如CIP中所述:

  

实现没有实际的许可对象,而Semaphore也没有   没有将分发的许可证与线程相关联,因此获得许可证   一个线程可以从另一个线程释放。你可以想到   以消费许可和获得许可获得;一个   信号量不仅限于创建它的许可数量。

对于您的方案,您可以共享计数器并使其变得易变或更好地使用AtomicInteger,因为它们使用CAS机制,在低争用下表现非常好。

相关问题