Java中的互斥量和信号量是什么?主要区别是什么?
答案 0 :(得分:133)
不幸的是,每个人都错过了信号量和互斥量之间最重要的区别; “所有权”的概念。
信号量没有所有权的概念,这意味着任何线程都可以释放信号量(这可能会导致许多问题,但可以帮助“死亡检测”)。而互斥锁确实具有所有权的概念(即,您只能释放已获得的互斥锁) 对于并发系统的安全编程,所有权非常重要。我总是建议使用互斥量优先于信号量(但有性能影响)。
互斥锁还可以支持优先级继承(可以帮助解决优先级倒置问题)和递归(消除一种类型的死锁)。
还应该指出,存在“二进制”信号量和“计数/一般”信号量。 Java的信号量是一个计数信号量,因此允许用大于1的值初始化它(而如指出的那样,互斥量只能是一个概念计数)。其他职位也指出了这方面的用处。
总而言之,除非您有多个资源需要管理,否则我总是会建议通过信号量使用互斥锁。
答案 1 :(得分:112)
可以计算信号量,而互斥量只能计为1。
假设您正在运行一个接受客户端连接的线程。该线程可以同时处理10个客户端。然后每个新客户端设置信号量直到它达到10.当信号量有10个标志,那么你的线程将不接受新的连接
Mutex通常用于保护东西。假设您的10个客户端可以访问系统的多个部分。然后,您可以使用互斥锁保护系统的一部分,因此当1个客户端连接到该子系统时,没有其他人可以访问。您也可以使用信号量来实现此目的。互斥锁是"Mutual Exclusion Semaphore"。
答案 2 :(得分:39)
Mutex基本上是互斥的。只有一个线程可以一次获取资源。当一个线程获取资源时,在拥有资源的线程释放之前,不允许其他线程获取资源。等待获取资源的所有线程都将被阻止。
信号量用于控制执行的线程数。将有固定的资源集。每当线程拥有相同的资源时,资源计数就会减少。当信号量计数达到0时,则不允许其他线程获取资源。线程被阻塞,直到其他线程拥有资源释放。
简而言之,主要区别在于一次允许多少线程获取资源?
答案 3 :(得分:8)
互斥锁用于对资源进行串行访问,而信号量则限制对资源的访问,最多可达到设定的数量。您可以将互斥锁视为访问计数为1的信号量。无论您将信号量计数设置为什么,线程都可以在资源被阻止之前访问资源。
答案 4 :(得分:3)
信号量是一种计数同步机制,而互斥量则不是。
答案 5 :(得分:3)
互斥锁通常被称为二进制信号量。虽然可以使用任何非零计数创建信号量,但互斥锁在概念上是一个上限为1的semeaphore。
答案 6 :(得分:2)
此问题有相关答案并链接到官方Java指南:Is there a Mutex in Java?
答案 7 :(得分:0)
你比较无与伦比的,从技术上来说,信号量和互斥量之间没有任何区别,这是没有意义的。 Mutex只是一个重要的名称,就像应用程序逻辑中的任何名称一样,它意味着您将信号量初始化为“1”,它通常用于保护资源或受保护变量以确保互斥。
答案 8 :(得分:0)
Mutex是二进制信号量。它必须用1初始化,以便满足先到先服务原则。这会将我们带到每个互斥锁的其他特殊属性:执行向下的人,必须是执行向上 的人。因此,我们已经获得了对某些资源的互斥。
现在您可以看到互斥锁是一般信号量的特例。
答案 9 :(得分:0)
同步对象信号量实现了经典的交通信号灯。交通信号灯控制对计数器共享资源的访问。如果计数器大于零,则授予访问权限;如果为零,则拒绝访问。计数器计算允许访问共享资源的权限。然后,要访问资源,线程必须从交通信号灯接收权限。通常,要使用交通信号灯,想要访问共享资源的线程会尝试获取许可证。如果交通灯计数大于零,则线程获得许可,并且交通灯计数减少。否则线程被锁定,直到它可以获得许可。当线程不再需要访问共享资源时,它会释放权限,因此交通灯计数会增加。如果有另一个线程在等待许可证,那么它在那时获得许可证。 Java的Semaphore类实现了这种机制。
Semaphore有两个建设者:
Semaphore(int num)
Semaphore(int num, boolean come)
num 指定许可的初始计数。然后num指定在给定时间可以访问共享资源的线程数。如果num为1,则它可以一次访问一个线程的资源。通过将来设置为true,您可以保证您正在等待的线程按其请求的顺序被授予权限。
答案 10 :(得分:0)
计数信号量。从概念上讲,信号量保持一组许可。如果需要,每个
acquire()
阻止,直到有许可证,然后接受。每个release()
都会添加一个许可证,可能会释放阻塞的收单方。但是,没有使用实际的许可对象;信号量只是保留可用数量并相应地采取行动。
信号量通常用于限制线程数,而不是可以访问某些(物理或逻辑)资源
Java没有内置的Mutex API。但它可以实现为二进制信号量。
信号量初始化为1,并且使用的信号量最多只有一个许可证可用作互斥锁。这通常称为二进制信号量,因为它只有两种状态:一种是可用的,或者是零可用的。
当以这种方式使用时,二进制信号量具有属性(与许多Lock实现不同)," lock"可以由所有者以外的线程释放(因为信号量没有所有权概念)。这在某些特定的上下文中很有用,例如死锁恢复。
Semaphore和Mutex之间的key differences:
信号量通过许可限制访问资源的线程数。 Mutex只允许一个线程访问资源。
没有线程拥有信号量。线程可以通过调用acquire()
和release()
方法更新许可数。互斥锁只能由持有锁的线程解锁。
当互斥锁与条件变量一起使用时,会有一个隐含的包围 - 很明显程序的哪一部分正在被保护 d。这不一定是信号量的情况,它可能被称为转向并发编程 - 它功能强大但很容易以非结构化,不确定的方式使用。