1。简介在本教程中,我们将讨论二进制信号量和可重入锁。另外,我们会将它们相互比较,看看哪一种最适合常见情况。2.什么是二进制信号量二进制信号量提供了一种访问单个资源的信号机制。换句话说,二进制信号量提供了一种互斥机制,一次只允许一个线程访问临界区。它只保留一次传递,因此二进制信号量只有两种状态:可用(count=1)和不可用(count=0)。我们使用Java中的Semaphore类来讨论一个简单的二进制信号量实现:SemaphorebinarySemaphore=newSemaphore(1);try{binarySemaphore.acquire();assertEquals(0,binarySemaphore.availablePermits());}catch(InterruptedExceptione){e.printStackTrace();}finally{binarySemaphore.release();assertEquals(1,binarySemaphore.availablePermits());}在这里我们可以观察到acquire方法将可用许可减少了一个。类似地,release方法将可用许可证递增1。此外,Semaphore类提供了一个公平性参数。当设置为true时,fairness参数确保请求线程获取许可的顺序(基于它们的等待时间):SemaphorebinarySemaphore=newSemaphore(1,true);3.什么是可重入锁?可重入锁是一种互斥机制,它允许线程在不发生死锁的情况下(多次)重新进入资源上的锁。每个进入锁的线程都会将保持计数递增1。同样,当请求解锁时,保持计数会递减。因此,资源被锁定,直到计数器归零。例如,让我们看一个使用Java中的ReentrantLock类的简单实现:ReentrantLockreentrantLock=newReentrantLock();try{reentrantLock.lock();assertEquals(1,reentrantLock.getHoldCount());assertEquals(true,reentrantLock.isLocked());}finally{reentrantLock.unlock();assertEquals(0,reentrantLock.getHoldCount());assertEquals(false,reentrantLock.isLocked());}在这里,lock方法将保持计数增加1并锁定资源。类似地,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类也支持公平参数:ReentrantLockreentrantLock=newReentrantLock(true);4.二进制信号量和可重入锁4.1.机制二进制信号量是一种信号机制,而可重入锁是一种锁定机制。4.2.所有权没有线程是二进制信号量的所有者。但是,最后成功锁定资源的线程是可重入锁的所有者。4.3.EssentialBinary信号量本质上是不可重入的,这意味着同一个线程不能重新获取临界区,否则会导致死锁。另一方面,可重入锁本质上允许同一个线程多次重新进入锁。4.4.灵活性二进制信号量通过允许自定义实现锁定机制和死锁恢复来提供更高级别的同步机制。因此,它为开发人员提供了更多控制权。但是,可重入锁是一种具有固定锁定机制的低级同步。4.5.可修改性二进制信号量支持等待和信号(在Java的信号量类中获取和释放)等操作,以允许任何进程修改可用的许可。另一方面,只有锁定/解锁资源的同一个线程才能修改可重入锁。4.6.死锁恢复二进制信号量提供了一种非所有权释放机制。因此,任何线程都可以释放二进制信号量的死锁恢复许可。相比之下,在可重入锁的情况下很难实现死锁恢复。例如,如果可重入锁的所有者线程进入休眠状态或无限期等待,则无法释放资源,从而导致死锁情况。5.总结在这篇简短的文章中,我们讨论了二进制信号量和可重入锁。首先,我们讨论了二进制信号量和可重入锁的基本定义,以及它们在Java中的基本实现。然后,我们根据力学、所有权和灵活性等参数对它们进行了比较。我们可以有把握地得出结论,二进制信号量提供了一种非基于所有权的互斥信号机制。同时可以进一步扩展,提供加锁功能,方便死锁恢复。另一方面,可重入锁为可重入互斥体提供基于所有者的锁定,可用作简单互斥体。本文转载自微信公众号《锅外大哥》,可通过以下二维码关注。转载本文请联系锅外老板公众号。
