Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用可变变量和信号量-Java_Java_Multithreading_Mutex_Semaphore_Volatile - Fatal编程技术网

使用可变变量和信号量-Java

使用可变变量和信号量-Java,java,multithreading,mutex,semaphore,volatile,Java,Multithreading,Mutex,Semaphore,Volatile,我从线程、信号量、可变变量等开始。 我想知道当我使用信号量时,是否有必要将变量定义为volatile,我的意思是: 有两个线程,一个增加,另一个减少变量,例如,很明显,在每次访问之前,我有一个互斥锁,在任何时候只有一个线程在“玩”变量 有必要将其定义为易失性 我想知道当我使用信号量时,是否有必要定义 易变为易变 我认为没有这样的限制。互斥是一种互斥信号量,是一种特殊的信号量变体,一次只允许一个锁存器。它相当于一个计数为1的普通计数信号量,并且要求它只能由锁定它的同一线程释放 如果我们专门针对Ja

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

有两个线程,一个增加,另一个减少变量,例如,很明显,在每次访问之前,我有一个互斥锁,在任何时候只有一个线程在“玩”变量

有必要将其定义为易失性

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

我认为没有这样的限制。互斥是一种互斥信号量,是一种特殊的信号量变体,一次只允许一个锁存器。它相当于一个计数为1的普通计数信号量,并且要求它只能由锁定它的同一线程释放

如果我们专门针对Java中的信号量进行讨论:信号量是许可证的计数器,acquire就像减量,它等待而不是降到零以下。它没有上限。如CIP中所述:

该实现没有实际的permit对象,而信号量有 不将分发的许可证与线程关联,因此在 一个线程可以从另一个线程释放。你可以想到 获取许可证作为使用许可证,释放许可证作为创建许可证;A. 信号量不限于创建时使用的许可数量

对于您的场景,您可以共享一个计数器并使其不稳定,或者更好地使用
AtomicInteger
,因为它们使用
CAS
机制,该机制在低争用情况下性能非常好。

来自API文档:

内存一致性影响:在调用 “release”方法,如
release()
发生在 在另一个线程中成功的“获取”方法,如
acquire()


因此,读/写由信号量保护的变量是安全的。不需要将它们声明为volatile,信号量不应代替synchronized使用,因为信号量即使初始化为互斥锁,也不会保持互斥锁,就像某些对象上的synchronized一样。的确,初始化为1的信号量一次只允许一个线程访问持有许可证的对象。但是持有许可证的线程并不拥有该许可证,任何其他线程都可以释放该许可证并获得该许可证。因此,两个线程可以同时访问同一个对象,如果两个线程都操作该对象,就会出现多线程问题,如更新丢失、读取过时等

在有两个线程的示例中,一个增加一个减少同一变量。互斥就足够了,不需要易变声明。这里我假设互斥是通过同步而不是信号量实现的


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

为什么不为此类操作使用
AtomicLong
?在同一个整数上正确高效地实现并发操作并不是那么容易。JDK中有现成的类可以帮你完成这项工作。为什么你在这里使用信号量?为什么你认为互斥是通过同步实现的,而他不使用同步的,只使用信号量?因为在这个例子中,他说互斥,但从来没有提过同步,问题是关于信号量和volatile的。由于没有明确提到,我希望他指的是同步,因为信号量不适合这种情况