不公平锁产生的原因的是acquire在enqueue之前,这样后来的线程有可能会较在等待队列中的等待者之前获得锁。barging这个词可以理解为闯入,插队。不公平锁会导致某些线程总是不排队就获得锁,而同时排在队尾的线程总是出现饥饿状态。那么如何获取公平锁呢,Doug Lee页给出了方案,很简单在acquire的时候,首先检查当前线程是否在队列中(对首),如在队列中即可获得,如不在队列中,则乖乖得排在队尾睡大觉(parking)等着排在前面的线程叫醒它(unparking)。
公平锁为啥会影响性能,从code上来看看公平锁仅仅是多了一项检查是否在队首会影响性能,如不是,那么又是在什么地方影响的?假如是闯入的线程,会排在队尾并睡觉(parking)等待前任节点唤醒,这样势必会比非公平锁添加很多paking和unparking的操作,我想这是影响公平锁性能的主要原因。
E文不好,不敢翻译,怕误了各位看官,还是直接贴原文吧
* <p><a name="barging">Because checks in acquire are invoked before
* enqueuing, a newly acquiring thread may <em>barge</em> ahead of
* others that are blocked and queued. However, you can, if desired,
* define <tt>tryAcquire</tt> and/or <tt>tryAcquireShared</tt> to
* disable barging by internally invoking one or more of the inspection
* methods, thereby providing a <em>fair</em> FIFO acquisition order.
* In particular, most fair synchronizers can define <tt>tryAcquire</tt>
* to return <tt>false</tt> if {@link #hasQueuedPredecessors} (a method
* specifically designed to be used by fair synchronizers) returns
* <tt>true</tt>. Other variations are possible.
*
* <p>Throughput and scalability are generally highest for the
* default barging (also known as <em>greedy</em>,
* <em>renouncement</em>, and <em>convoy-avoidance</em>) strategy.
* While this is not guaranteed to be fair or starvation-free, earlier
* queued threads are allowed to recontend before later queued
* threads, and each recontention has an unbiased chance to succeed
* against incoming threads. Also, while acquires do not
* "spin" in the usual sense, they may perform multiple
* invocations of <tt>tryAcquire</tt> interspersed with other
* computations before blocking. This gives most of the benefits of
* spins when exclusive synchronization is only briefly held, without
* most of the liabilities when it isn't. If so desired, you can
* augment this by preceding calls to acquire methods with
* "fast-path" checks, possibly prechecking {@link #hasContended}
* and/or {@link #hasQueuedThreads} to only do so if the synchronizer
* is likely not to be contended.
分享到:
相关推荐
本文将深入探讨ReentrantLock的原理,特别是其公平锁与非公平锁的概念,以及ReentrantLock的源码解析。 首先,我们了解什么是可重入锁。可重入锁允许一个线程多次获取同一锁,而不被阻塞。当一个线程已经持有了锁,...
`ReentrantLock`是Java并发编程...在实际开发中,`ReentrantLock`常用于需要复杂同步逻辑的场景,如分布式锁、读写锁等。了解并熟练使用`ReentrantLock`能帮助开发者更好地解决并发问题,提高程序的并发性能和健壮性。
ReentrantLock 实现原理详解 ...在实际应用中,ReentrantLock 可以用于各种需要同步的场景,例如多线程之间的数据共享、线程安全的操作等。ReentrantLock 的使用可以确保线程安全,避免出现死锁和活锁等问题。
Lock、Synchronized 和 ReentrantLock 是 Java 中三种常用的同步机制,每种机制都有其特点和使用场景。下面对这三种机制进行详细的分析和比较。 一、Synchronized Synchronized 是 Java 中最基本的同步机制,它...
ReentrantLock通过AQS提供了强大的锁管理能力,尤其在非公平锁模式下,即使在高并发场景下也能表现出良好的性能。通过对上述流程的分析可以看出,ReentrantLock的设计充分考虑了各种实际应用场景的需求,在保证线程...
ReentrantLock的这些特性使得它在某些复杂的并发场景下更为适用,例如,当需要精确控制线程间的交互,或者需要在等待期间响应中断信号时。不过,对于简单的同步控制,使用synchronized通常更简洁。在选择使用哪种锁...
- 不支持公平锁,即线程获取锁的顺序并不总是按照它们请求锁的时间顺序进行。 - 无法中断正在等待获取锁的线程,除非抛出异常或者调用`Thread.interrupt()`。 - 不能知道哪个线程持有锁,也无法知道锁的状态。 *...
公平锁虽然遵循了公平原则,但可能会导致整体性能下降,因为线程在等待时可能会长时间不活跃。非公平锁虽然可能导致某些线程等待时间变长,但在大多数情况下,它的吞吐量通常优于公平锁。 总的来说,这段代码展示...
释放锁时,持有次数会减少,只有当持有次数降为零时,锁才会真正释放。 ### 4. 公平锁与非公平锁 - **公平锁**:遵循FIFO(先进先出)原则,等待最久的线程将首先获得锁。这确保了线程的等待时间是确定的,但可能...
总结,ReentrantLock通过内部类和AQS实现了高度定制化的锁机制,非公平锁和公平锁的实现方式不同,分别适用于不同的并发场景。理解其工作原理有助于我们在实际开发中更有效地利用并发资源,提高程序性能。
- 它支持公平和非公平两种获取锁的策略,默认为非公平锁。 2. **重要特性**: - **可中断等待**:通过`lock.tryLock()`和`lock.tryLock(long timeout, TimeUnit unit)`方法,可以在等待获取锁时响应中断。 - **...
ReentrantLock分为公平锁和非公平锁,公平锁保证了线程按照等待顺序获取锁,而非公平锁则不保证这一特性。 ### 3. volatile关键字 volatile关键字用于保证变量的可见性和有序性。它确保了当一个线程修改了volatile...
在没有明确性能瓶颈的情况下,不应盲目地将Synchronized替换为ReentrantLock,反之亦然。 总结来说,Synchronized和ReentrantLock是Java多线程编程中的两种重要锁机制。Synchronized以其简洁性和自动释放的特性赢得...
2. **公平性**:可以通过构造函数设置为公平锁,保证等待最久的线程优先获得锁,而`synchronized`默认是非公平的。 3. **尝试获取锁**:`tryLock()`方法允许尝试获取锁,不阻塞,可以设置超时时间。 4. **锁分离**:...
ReentrantLock有两种构造方法,一种不接受参数,默认采用非公平策略,另一种接受一个布尔参数,可以指定公平策略。 公平策略确保等待时间最长的线程优先获取锁,遵循先来后到的原则,但这可能导致更高的线程调度...
- **公平锁**:通过实现FairSync,ReentrantLock也可设置为公平锁,保证线程按照等待队列的顺序获取锁。 - **超时机制**:ReentrantLock的tryLock(long time, TimeUnit unit)方法允许设置等待时间,超时未获取到...
通过对两者的特性进行对比,详细解析了ReentrantLock在灵活性、公平性和中断响应等方面的优点。并通过源码解读,阐述了线程如何获取和释放锁的具体流程。 适合人群:具有一定的Java编程基础,对并发编程感兴趣的软件...
ReentrantLock的使用场景非常广泛,例如,可以用于解决多线程访问共享资源的问题、实现线程之间的同步访问资源、避免死锁的出现等等。 在Java中,ReentrantLock是Lock接口的实现类,提供了加锁和解锁的方法,可以...
ReentrantLock的一个关键特性是可设置公平性,这意味着线程可以按照它们请求锁的顺序来获取锁,而synchronized则是非公平的。此外,ReentrantLock还支持条件变量,允许更复杂的同步控制,如等待队列的管理。 性能...