为了账号安全,请及时绑定邮箱和手机立即绑定

锁之ReentrantLock

标签:
JavaScript

Lock源码

public interface Lock {  //获取锁  void lock(); /**  *当前线程的锁没有中断才能获取锁  * if (Thread.interrupted())  *        throw new InterruptedException();  */  void lockInterruptibly() throws InterruptedException;    //获取锁是否成功。true表示获取到锁,false表示没有获取到锁  boolean tryLock();     // 尝试获取锁,并等待指定的时间   boolean tryLock(long time, TimeUnit unit) throws InterruptedException;   // 释放锁   void unlock();   // LOCK条件   Condition newCondition();}

ReentrantLock源码

public class ReentrantLock implements Lock, java.io.Serializable {  // 同步器,是整个锁机制的实现者  private final Sync sync;  // 定义的抽象静态内部类。实现基本的功能    abstract static class Sync extends AbstractQueuedSynchronizer {         // 抽象方法。由公平锁和非公平锁自己实现        abstract void lock();            // 释放锁            protected final boolean tryRelease(int releases) {                  // 锁的计数器。释放一次计数器减1,直到为0,则整个锁完全释放,才能被其他线程获取该锁。            int c = getState() - releases;                        // 此类型锁是可重入锁。因此是以thread为粒度的。必须判断当前线程是否与持有锁线程一致。            if (Thread.currentThread() != getExclusiveOwnerThread())                throw new IllegalMonitorStateException();            boolean free = false;                        // 当锁的计数器为0时,整个锁释放。            if (c == 0) {                free = true;                setExclusiveOwnerThread(null);            }            setState(c);            return free;        }                // 默认实现的一个非公平锁的获取尝试获取方法                final boolean nonfairTryAcquire(int acquires) {            final Thread current = Thread.currentThread();            int c = getState();                        // 如果锁的计数器为0,则表示没有锁。            if (c == 0) {                            //  compareAndSetState方法实际调用的是unsafe.compareAndSwapInt(this, stateOffset, expect, update);                // 直接操作的JVM。并给当前线程持有锁。                                if (compareAndSetState(0, acquires)) {                    setExclusiveOwnerThread(current);                    return true;                }            }                        // 如果计数器不为0,但当前线程就是持有锁的线程。则锁的计数器增加。            else if (current == getExclusiveOwnerThread()) {                int nextc = c + acquires;                if (nextc < 0) // overflow                    throw new Error("Maximum lock count exceeded");                setState(nextc);                return true;            }                        // 如果计数器不为0,同时当前线程不是持有锁的线程。则加锁失败。            return false;        }     }  // 非公平所的实现器  static final class NonfairSync extends Sync {             // 加锁。         final void lock() {            if (compareAndSetState(0, 1)) //非公平加锁                setExclusiveOwnerThread(Thread.currentThread());            else                acquire(1); // 如果加锁不成功,则放入队列        }          // 试着加锁          protected final boolean tryAcquire(int acquires) {            return nonfairTryAcquire(acquires);        }    }    // 公平锁    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;        }    }}

AbstractQueuedSynchronizer源码

 // 存储队列锁的存储node.是一个双向的链表结构。 static final class Node {   // 前一个node   volatile Node prev;     // 后一个node     volatile Node next;     // 该node所对应的线程     volatile Thread thread;         } // 整个队列锁的第一个node. private transient volatile Node head; // 整个队列锁的第后个node. private transient volatile Node tail; // 锁的状态。计数器 private volatile int state; // 加锁的关键点。通过navtive 方法unsafe直接操作CPU。 protected final boolean compareAndSetState(int expect, int update) {        return unsafe.compareAndSwapInt(this, stateOffset, expect, update); }

总结

Lock这种以类的方式来实现锁的机制。
优点:
1.加锁和释放锁独立,可以分开来控制。
2.tryLock的方法可以尝试加锁,不会像sychnorized一致阻塞。
3.实现了公平锁和非公平锁。sychnorized只能是非公平锁。

缺点:
1.增加了代码的复杂度。
2.相比sychnorized的自动加锁和释放锁,Lock需要手动,容易忘记,从而出现重大的隐患。

经过JDK的不断更新,sychnorized与lock的性能相差不大,官方建议使用sychnorized方法加锁。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消