java中什么是互斥_关于多线程:Java中的互斥量和信号量是什么? 主要区别是什么?...

Java中的互斥量和信号量是什么? 主要区别是什么?

stackoverflow.com/questions/4039899/中的类似查询

不幸的是,每个人都错过了信号量和互斥量之间最重要的区别。"所有权"的概念。

信号量没有所有权的概念,这意味着任何线程都可以释放信号量(这本身可能导致许多问题,但可以帮助进行"死亡检测")。互斥锁确实具有所有权的概念(即,您只能释放已获取的互斥锁)。

所有权对于并发系统的安全编程非常重要。我总是建议您优先使用互斥锁而不是信号量(但会影响性能)。

互斥对象还可以支持优先级继承(可以帮助解决优先级倒置问题)和递归(消除一种类型的死锁)。

还应该指出,存在"二进制"信号量和"计数/通用"信号量。 Java的信号量是一个计数信号量,因此允许使用大于1的值对其进行初始化(而正如所指出的,互斥量只能在概念上计数为1)。其他职位已经指出了这一点的有用性。

综上所述,除非您有多个资源要管理,否则我总是建议在信号量上使用互斥量。

Feabhass的答案非常重要-互斥锁会检查试图释放该互斥锁的线程实际拥有它。我已经将其作为面试问题,因此值得记住。

信号量可以计数,而互斥量只能计数为1。

假设您正在运行一个接受客户端连接的线程。该线程可以同时处理10个客户端。然后,每个新客户端将信号量设置为达到10。当信号量有10个标志时,您的线程将不接受新连接

互斥锁通常用于保护物品。假设您的10个客户端可以访问系统的多个部分。然后,您可以使用互斥锁保护系统的一部分,因此当1个客户端连接到该子系统时,其他任何人都不能访问。您也可以为此使用信号量。互斥锁是"互斥信号量"。

这不是真的。同一线程可以多次进入同一个互斥锁,因此需要保持一个计数,以确保入口和出口保持平衡。

@finnw,通常有两种互斥类型:递归和非递归。 Java默认情况下是否使用递归类型?

@ edA-qa mort-ora-y,Java VM或API规范中未使用" Mutex"一词,因此我假设它是指内置于每个对象中的监视器,这也类似于称为Mutex的Win32对象。 ReentrantLock也是如此。所有这些都是递归的。我不知道任何非递归互斥体的"真实世界"示例(我仅在教科书中看到过它们),因此我没有考虑它们。

非递归互斥锁可以通过使用计数为1的信号量来实现。如果要防止递归调用,这可能很有用。这有实际用途,Ive亲自在大型项目中使用它来检测初始化代码中的循环(A初始化B,然后尝试再次初始化A)。

在C ++ 11(C ++ 0x)标准中,互斥锁是非递归的。它们还为需要的人提供了单独的recursive_mutex。我知道我们在这里谈论Java,但是现在我们许多人正在跨语言进行编码。

我只是想提出一点,我认为尝试将互斥体描述为信号量的一种特殊情况通常对初学者没有帮助。是的,互斥锁可以实现为信号量,并具有附加的约束,该约束不允许传递,并且获取该互斥锁的线程必须将其返回,但将它们更容易地概念化为锁。

互斥体基本上是互斥的。一次只有一个线程可以获取资源。当一个线程获取资源时,在拥有该资源的线程释放之前,不允许其他线程获取资源。所有等待获取资源的线程都将被阻塞。

信号量用于控制执行的线程数。将有一组固定的资源。每当线程拥有相同资源时,资源计数将减少。当信号量计数达到0时,则不允许其他线程获取资源。线程将被阻塞,直到拥有资源的其他线程释放为止。

简而言之,主要区别是允许多少个线程一次获取资源?

互斥锁-它是一个。

信号量-其DEFINED_COUNT,(与信号量一样多)

非常好的解释..谢谢

很棒的总结!

好实用的解释!

互斥锁用于对资源的串行访问,而信号量则限制对资源的访问(最多设置一个数字)。您可以将互斥锁视为访问计数为1的信号量。无论将信号量计数设置为什么,线程都可以在阻塞资源之前访问资源。

互斥锁通常称为二进制信号量。虽然可以使用任何非零计数创建信号量,但互斥量在概念上是计数上限为1的信号量。

信号量是一种计数同步机制,互斥体不是。

这个问题有相关的答案,并链接到Java官方指南:Java中是否有Mutex?

信号:

A counting semaphore. Conceptually, a semaphore maintains a set of permits. Each acquire() blocks if necessary until a permit is available, and then takes it. Each release() adds a permit, potentially releasing a blocking acquirer. However, no actual permit objects are used; the Semaphore just keeps a count of the number available and acts accordingly.

信号量通常用于限制线程数量,使其无法访问某些(物理或逻辑)资源

Java没有内置的Mutex API。但是可以将其实现为二进制信号量。

A semaphore initialized to one, and which is used such that it only has at most one permit available, can serve as a mutual exclusion lock. This is more commonly known as a binary semaphore, because it only has two states: one permit available, or zero permits available.

当以这种方式使用时,二进制信号量具有属性(与许多Lock实现不同),该"锁"可以由所有者以外的线程释放(因为信号量没有所有权概念)。这在某些特殊情况下(例如死锁恢复)很有用。

因此,信号量和互斥量之间的主要区别是:

信号量通过允许限制访问资源的线程数。 Mutex仅允许一个线程访问资源。

没有线程拥有信号量。线程可以通过调用acquire()和release()方法来更新许可数量。互斥锁只能由持有锁的线程来解锁。

当互斥锁与条件变量一起使用时,会出现一个括号,即程序的哪个部分受到保护。信号量不一定是这种情况,可以将其称为并发编程。它功能强大,但以非结构化,不确定的方式易于使用。

同步信号灯的对象实现了经典的交通信号灯。交通信号灯控制对计数器共享资源的访问。如果计数器大于零,则授予访问权限。如果为零,则拒绝访问。计数器计算允许访问共享资源的权限。然后,要访问资源,线程必须从交通信号灯接收许可。通常,要使用交通信号灯,想要访问共享资源的线程会尝试获取许可。如果交通信号灯计数大于零,则线程获取许可,并且交通信号灯计数递减。否则,线程将被锁定,直到获得许可为止。当线程不再需要访问共享资源时,它会释放权限,因此交通信号灯计数会增加。如果还有另一个线程在等待许可,则它会在那时获取许可。 Java的Semaphore类实现了此机制。

信号量具有两个生成器:

Semaphore(int num)

Semaphore(int num, boolean come)

num指定许可的初始计数。然后num指定在给定时间可以访问共享资源的线程数。如果num为1,则它可以一次访问一个线程的资源。通过将true设置为true,可以保证正在等待的线程按请求的顺序被授予权限。

互斥量是二进制信号量。必须将其初始化为1,以便满足"先来先服务"原则。这将我们带到每个互斥锁的另一个特殊属性:失败的互斥对象必须是执行互斥的互斥对象。因此,我们已经在某些资源上获得了互斥。

现在您可以看到互斥锁是一般信号量的特例。

您可以比较无与伦比的信号,从技术上讲,信号量和互斥量之间没有区别,这是没有意义的。

Mutex只是一个有意义的名称,就像您的应用程序逻辑中的任何名称一样,它表示您将信号量初始化为" 1",它通常用于保护资源或受保护的变量以确保互斥。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值