什么是Java中的公平锁? 您所在的位置:网站首页 java中各种锁 什么是Java中的公平锁?

什么是Java中的公平锁?

2023-03-15 03:12| 来源: 网络整理| 查看: 265

一直想分析下公平锁和非公平锁在Java中的实现。

公平锁(Fair):加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得

非公平锁(Nonfair):加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待

----------------------------------------------------------------------------------------------------

首先Java中的ReentrantLock 默认的lock()方法采用的是非公平锁。

也就是不用考虑其他在排队的线程的感受,lock()的时候直接询问是否可以获取锁,而不用在队尾排队。

下面分析下公平锁的具体实现。

重点关注java.util.concurrent.locks.AbstractQueuedSynchronizer类

几乎所有locks包下的工具类锁都包含了该类的static子类,足以可见这个类在java并发锁工具类当中的地位。

这个类提供了对操作系统层面线程操作方法的封装调用,可以帮助并发设计者设计出很多优秀的API

ReentrantLock当中的lock()方法,是通过static 内部类sync来进行锁操作

public void lock() { sync.lock(); } //定义成final型的成员变量,在构造方法中进行初始化 private final Sync sync; //无参数默认非公平锁 public ReentrantLock() { sync = new NonfairSync(); } //根据参数初始化为公平锁或者非公平锁 public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }

-----------------------------------------明日再更--------------------------

11月11日更

介绍非公平锁

static final class NonfairSync extends Sync { private static final long serialVersionUID = 7316153563782823691L; /** * Performs lock. Try immediate barge, backing up to normal * acquire on failure. */ final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } }

那么调用默认构造方法构建的ReentrantLock的lock()方法的时候,其实调用的是NonfairSync对象的lock()方法,

protected final boolean compareAndSetState(int expect, int update) { // See below for intrinsics setup to support this return unsafe.compareAndSwapInt(this, stateOffset, expect, update); }

java不能直接访问操作系统底层,而是通过本地方法来访问。Unsafe类提供了硬件级别的原子操作,

unsafe对象是通过compareAndSwapInt方法实现的CAS操作

/** * 比较obj的offset处内存位置中的值和期望的值,如果相同则更新。此更新是不可中断的。 * * @param obj 需要更新的对象 * @param offset obj中整型field的偏移量 * @param expect 希望field中存在的值 * @param update 如果期望值expect与field的当前值相同,设置filed的值为这个新值 * @return 如果field的值被更改返回true */ public native boolean compareAndSwapInt(Object obj, long offset, int expect, int update);

CAS操作有3个操作数,内存值M,预期值E,新值U,如果M==E,则将内存值修改为U,否则啥都不做。

于是通过上面的CAS操作,判断state变量的值,如果是0(表明该锁没有被线程占用),则可以设置state为1,占有该锁。

从这里我们就可以看到非公平锁的不公平性,后面我们会看到有一个队列的线程可能在等待该锁的释放,而新来的线程我们看到直接询问是否可以拿到锁。

-------------------------------------------------------------------



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有