cnblogs ext protected 操作 nal 对象 node set
reentrantlock对象,里面有一个state属性,volatile的,对其进行cas操作,可以作为锁使用。
ReentrantLock lock = new ReentrantLock();
lock.lock();方法调用的是sync.lock()方法,sync是ReentrantLock的全局变量名,如果调用无参构造函数,生成的是一个非公平的lock,调用带参数可以确定是公平锁还是非公平。
非公平锁,的lock方法,调用的是,
- final void lock() {
- if (compareAndSetState(0, 1))
- setExclusiveOwnerThread(Thread.currentThread());
- else
- acquire(1);
- }
逻辑是,把state变量,也就是那个锁,置换成1的状态,加锁,如果成功了,就把lock对象当前的锁定线程赋值为当前线程。
如果没成功,说明现在是加锁的,那么执行acqire()方法
- public final void acquire(int arg) {
- if (!tryAcquire(arg) &&
- acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
- selfInterrupt();
- }
逻辑是,先执行tryAcquire方法
- protected final boolean tryAcquire(int acquires) {
- return nonfairTryAcquire(acquires);
- }
- final boolean nonfairTryAcquire(int acquires) {
- final Thread current = Thread.currentThread();
- int c = getState();
- if (c == 0) {
- if (compareAndSetState(0, acquires)) {
- setExclusiveOwnerThread(current);
- return true;
- }
- } else if (current == getExclusiveOwnerThread()) {
- int nextc = c + acquires;
- if (nextc < 0) // overflow
- throw new Error("Maximum lock count exceeded");
- setState(nextc);
- return true;
- }
- return false;
- }
就是先试着再去加锁一次,如果还没成功,再检测加锁的是否是当前线程,如果是的话,那么重入,把state值加一
如果以上都不成功,那么返回false
接下来看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);
- }
- }
这个是AbstractQueuedSynchronizer抽象类的方法,给Sync继承,
- private Node addWaiter(Node mode) {
- Node node = new Node(Thread.currentThread(), mode);
- // Try the fast path of enq; backup to full enq on failure
- Node pred = tail;
- if (pred != null) {
- node.prev = pred;
- if (compareAndSetTail(pred, node)) {
- pred.next = node;
- return node;
- }
- }
- enq(node);
- return node;
- }
先看addwaiter方法,在Sync对象的尾部(lock对象其实只是对sync对象的封装,sync才是真正的锁,sync对象内部除了一个volatile的锁state,还有两个node节点(node节点内部有一个前驱指针,一个后续指针,一个存线程引用的变量),一个指向头(头内部没有有用数据),一个指向尾部tail,保留一个等待这个锁的线程队列,
在这里实现公平非公平,addwaiter方法,就是把当前没有获取到锁的线程,做成一个node封装起来,放在队列最后,并返回这个node。
acquireQueued方法,有空再看
ReentrantLock.lock();
来源: http://www.bubuko.com/infodetail-2285455.html