java高并发、多线程(六)--ReentrantLock

ReentrantLock

ReentrantLock源码结构:

public class ReentrantLock implements Lock, java.io.Serializable {
    private final Sync sync;
    //锁实现类
    abstract static class Sync extends AbstractQueuedSynchronizer {/*...*/}
    //非公平锁实现
    static final class NonfairSync extends Sync {/*...*/}
    //公平锁实现
    static final class FairSync extends Sync {/*...*/}
    //默认为非公平锁
    public ReentrantLock() {
        sync = new NonfairSync();
    }
    //参数为true为公平锁
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }  
}

从上面的结构可以知道,ReentrantLock 类内部包含Sync 、NonfairSync 、FairSync 3个内部类,其中NonfairSync 、FairSync均继承自Sync ,二则差异主要是各自实现的公平与非公平锁。

NonfairSync类

static final class NonfairSync extends Sync {
		//加锁
        final void lock() {}
        //尝试以独占模式获取锁
        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
}

从上面源码可以知道,NonfairSync主要实现了lock()以及tryAcquire(int)方法。

tryAcquire(int)

上一节我们介绍AQS的时候说到子类根据各自需求需要实现几个方法,这里NonfairSync 实现tryAcquire(尝试以独占模式获取锁)方法,因此NonfairSync 是使用的独占锁的模式:

 //尝试以独占模式获取锁
 protected final boolean tryAcquire(int acquires) {
     return nonfairTryAcquire(acquires);
 }

从代码中可以看出tryAcquire调用的父类Sync的nonfairTryAcquire方法。我们再继续看一下nonfairTryAcquire的实现:

final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            //获取当前线程的同步状态state
            int c = getState();
            //为0时表示当前线程未获取到锁
            if (c == 0) {
            	//利用CAS进行加锁
                if (compareAndSetState(0, acquires)) {
                //加锁成成功则设置线程拥有独占访问
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            //判断当前线程是否拥有独占访问
            else if (current == getExclusiveOwnerThread()) {
            	//累加参数acquires
                int nextc = c + acquires;
                //溢出,如果并发量特别大需要注意
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                //设置state
                setState(nextc);
                return true;
            }
            return false;
}

lock()

   final void lock() {
   		//CAS加锁
       if (compareAndSetState(0, 1))
       //成功,则设置线程拥有独占访问
           setExclusiveOwnerThread(Thread.currentThread());
       else
       //调用父类AQS具体实现
           acquire(1);
   }

接着我们继续查看AQS中acquire(int)方法:

public final void acquire(int arg) {
		//尝试以独占模式获取锁
        if (!tryAcquire(arg) &&
        //获取不到则加入到等待队列中获取
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            //中断当前线程
            selfInterrupt();
}

继续查看addWaiter():

private Node addWaiter(Node mode) {
		//创建node
        Node node = new Node(Thread.currentThread(), mode);
        // 获取尾指针node
        Node pred = tail;
        if (pred != null) {
        	//将创建的node的前驱节点设置为原尾节点
            node.prev = pred;
            //同步设置当前节点为尾节点
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        //入队
        enq(node);
        return node;
}

继续查看acquireQueued():

final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
            	//获取前驱节点
                final Node p = node.predecessor();
                //前驱节点为头节点,尝试获取独占锁
                if (p == head && tryAcquire(arg)) {
                	//设置头节点为当前节点
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                //检查更新等待状态
                if (shouldParkAfterFailedAcquire(p, node) &&
                	//中断线程
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
            //取消获取锁操作
                cancelAcquire(node);
        }
}

继续查看shouldParkAfterFailedAcquire():

private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
		//获取等待状态
        int ws = pred.waitStatus;
        //如果状态为SIGNAL,正常等待
        if (ws == Node.SIGNAL)
            return true;
        //大于0即CANCELLED状态
        if (ws > 0) {
        //跳过取消的节点
            do {
                node.prev = pred = pred.prev;
            } while (pred.waitStatus > 0);
            pred.next = node;
        } else {
            //修改等待状态为SIGNAL
            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
        }
        return false;
    }

继续查看parkAndCheckInterrupt():

private final boolean parkAndCheckInterrupt() {
		//利用LockSupport的park方法进行阻塞
        LockSupport.park(this);
        //返回阻塞状态
        return Thread.interrupted();
}

FairSync 类

下面我们来看看公平锁的具体实现:

static final class FairSync extends Sync {
        final void lock() {
            acquire(1);
        }
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
            	//查看队列是否还有未执行的任务
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }

继续查看hasQueuedPredecessors()的具体实现:

public final boolean hasQueuedPredecessors() {
        Node t = tail; 
        Node h = head;
        Node s;
        //是否为空队列或者当前线程是否为队列的头
        return h != t &&
            ((s = h.next) == null || s.thread != Thread.currentThread());
    }

Sync类

关于Sync类,我们这里就简单的看一下他的tryRelease(int)以及isHeldExclusively()方法的具体实现:

protected final boolean tryRelease(int releases) {
//	减去同步状态值
     int c = getState() - releases;
     if (Thread.currentThread() != getExclusiveOwnerThread())
         throw new IllegalMonitorStateException();
     boolean free = false;
     //未获取到锁
     if (c == 0) {
         free = true;
         //设置独占为null
         setExclusiveOwnerThread(null);
     }
     //修改同步状态
     setState(c);
     return free;
}
protected final boolean isHeldExclusively() {
     return getExclusiveOwnerThread() == Thread.currentThread();
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值