1.概述
在本教程中,我们将探讨二进制信号量和可重入锁。另外,我们将彼此进行比较,以了解哪种情况最适合常见情况。
2.什么是二进制信号量?
二进制信号量提供了对单个资源的访问的信令机制。换句话说,二进制信号量提供了互斥性,该互斥性仅允许一个线程一次访问关键部分。
为此,它仅保留一个许可证可供访问。因此,二进制信号量只有两种状态:一个许可可用或零许可可用。
让我们使用Java中可用的Semaphore类讨论二进制信号量的简单实现:
Semaphore binarySemaphore = new Semaphore(1); try { binarySemaphore.acquire(); assertEquals(0, binarySemaphore.availablePermits()); } catch (InterruptedException e) { e.printStackTrace(); } finally { binarySemaphore.release(); assertEquals(1, binarySemaphore.availablePermits()); }
在这里,我们可以看到, acquire方法将可用许可证减少了一个。同样, release方法将可用许可证增加了一个。
此外, Semaphore类提供fairness参数。当设置为true , fairness参数确保请求线程获得许可的顺序(基于它们的等待时间):
Semaphore binarySemaphore = new Semaphore(1, true);
3.什么是可重入锁?
可重入锁是一种互斥机制,该机制允许线程(多次)重新进入资源锁,而不会出现死锁情况。
进入锁的线程每次都会将保持计数增加一。同样,请求解锁时,保留计数会减少。因此,资源被锁定,直到计数器返回零为止。
例如,让我们看一下使用Java中提供的ReentrantLock类的简单实现:
ReentrantLock reentrantLock = new ReentrantLock(); try { reentrantLock.lock(); assertEquals(1, reentrantLock.getHoldCount()); assertEquals(true, reentrantLock.isLocked()); } finally { reentrantLock.unlock(); assertEquals(0, reentrantLock.getHoldCount()); assertEquals(false, reentrantLock.isLocked()); }
在这里, lock方法将保持计数增加一并锁定资源。类似地,如果保持计数为零,那么unlock方法会减少保持计数并解锁资源。
当线程重新进入锁时,它必须请求解锁相同的次数才能释放资源:
reentrantLock.lock(); reentrantLock.lock(); assertEquals(2, reentrantLock.getHoldCount()); assertEquals(true, reentrantLock.isLocked()); reentrantLock.unlock(); assertEquals(1, reentrantLock.getHoldCount()); assertEquals(true, reentrantLock.isLocked()); reentrantLock.unlock(); assertEquals(0, reentrantLock.getHoldCount()); assertEquals(false, reentrantLock.isLocked());
与Semaphore类类似, ReentrantLock类也支持fairness参数:
ReentrantLock reentrantLock = new ReentrantLock(true);
4.二进制信号量与可重入锁定
4.1。机制
二进制信号量是一种信号机制,而可重入锁是一种锁定机制。
4.2。所有权
没有线程是二进制信号量的所有者。但是,成功锁定资源的最后一个线程是可重入锁的所有者。
4.3。性质
二进制信号量本质上是不可重入的,这意味着同一线程无法重新获取关键部分,否则将导致死锁情况。
另一方面,重入锁本质上允许通过同一线程多次重入锁。
4.4。灵活性
二进制信号量通过允许自定义实现锁定机制和死锁恢复来提供更高级别的同步机制。因此,它赋予了开发人员更多的控制权。
但是,可重入锁定是具有固定锁定机制的低级同步。
4.5。修改
二进制信号量支持诸如等待和信号(在Java的Semaphore类的情况下为获取和释放)之类的操作,以允许任何进程修改可用的许可。
另一方面,只有锁定/解锁资源的同一线程才能修改可重入锁定。
4.6。死锁恢复
二进制信号量提供了一种非所有权释放机制。因此,任何线程都可以释放对二进制信号量进行死锁恢复的许可。
相反,在重入锁的情况下,很难实现死锁恢复。例如,如果可重入锁的所有者线程进入睡眠或无限等待状态,则将无法释放资源,从而导致死锁。
5.结论
在这篇简短的文章中,我们探讨了二进制信号量和可重入锁。
首先,我们讨论了二进制信号量和可重入锁的基本定义,以及Java的基本实现。然后,我们根据一些参数(例如机制,所有权和灵活性)相互比较。
我们当然可以得出结论,二进制信号量为互斥提供了一种基于非所有权的信号机制。同时,它可以进一步扩展以提供具有轻松死锁恢复的锁定功能。
另一方面,可重入锁提供了基于所有者锁定功能的可重入互斥,可作为简单的互斥锁使用。
0 评论