JUC框架学习--lock锁总结

Locke 接口: 支持予以不同(重入,公平等)的锁规则: 1. 公平锁 2.非公平锁 3.可重入锁
     实现lock接口的锁,其构造方法中有 boolean fair参数控制,当fair为
     true时,是公平锁,反之为非公平锁。默认是非公平锁。以ReentrantLock为例源码如下:
     无参构造:
    /**
       * Creates an instance of {@code ReentrantLock}.
       * This is equivalent to using {@code ReentrantLock(false)}.
       */
      public ReentrantLock() {
           sync = new NonfairSync();
      }
      有参构造:
        /**
           * Creates an instance of {@code ReentrantLock} with the
           * given fairness policy.
           *
           * @param fair {@code true} if this lock should use a fair ordering policy
           */
          public ReentrantLock(boolean fair) {
              sync = fair ? new FairSync() : new NonfairSync();
          }
        对于锁里面一定会有一个FIFO的同步队列进行锁定控制。(非公平锁和公平锁),其
         源码如下:公平;FairSync(), NonfairSync()
           public ReentrantReadWriteLock(boolean fair) {
                 sync = fair ? new FairSync() : new NonfairSync();
                 readerLock = new ReadLock(this);
                 writerLock = new WriteLock(this);
             }
  读写锁 : 和lock类似的方式定义了一些读者可以共享而写入者独占的锁。
 同步对列提供了两类锁机制: 1. 独占锁 2. 共享锁。 ReadWriteLock中的readLock()和writeLock()分别是共享锁和独占锁。



 无障碍锁:StampedLock(加强版的读写锁),读锁和写锁是完全互斥的。也就是说在进行数据输入的时候,读取操作需要进行等待,
 等待写锁释放之后才可以继续进行读锁相应的处理。
 StampedLock提供了两类锁:1.悲观锁 :会假设互斥锁的装填一直都会存在,默认的处理形式都是悲观锁。
                        2.乐观锁 :假设在读取的时候没有这么多的写入操作,如果真的发生了写入,那么就需要进行一个状态
                        判断,通过状态的结果来巨鼎是否需要进行锁的处理。
              主要方法:1. 获取读悲观锁,同时获取一个标记 :public long readLock();
                       2. 获取读悲观锁,同时获取一个标记 :public long writeLock();
                       3. 获取读的乐观锁: public 龙tryOptimisticRead();
                       4. 进行指定标记的验证 :public boolean validate (long stamp);
                       5. 释放锁 :public void unlick(long stamp);
                       6. 释放读锁 :public void unlickRead(long stamp);
                       7. 释放写锁 :public void unlickWrite(long stamp);

互斥锁:ReentrantLock :普通可重用的互斥锁进行操作。lock 于ReentranLock 实现的只是一个最为基础的锁的处理机制,利用Lock ()
 与unlock()方法就可以构建出一个类似同步代码块的机构。但是其结构要比通过代码块更加简单。
 扩展: 可重入锁
    1.synchronized可重入,因为加锁和解锁自动进行,不必担心最后是否释放锁;ReentrantLock也可重入,但加锁和解锁需要手动进行,
且次数需一样,否则其他线程无法获得锁。
    2.synchronized是独占锁,加锁和解锁的过程自动进行,易于操作,但不够灵活。ReentrantLock也是独占锁,加锁和解锁的过程需要手动进行,
不易操作,但非常灵活。
    3.synchronized不可响应中断,一个线程获取不到锁就一直等着;ReentrantLock可以相应中断。

ReentrantLock好像比synchronized关键字没好太多,我们再去看看synchronized所没有的,一个最主要的就是ReentrantLock还可以实现
公平锁机制。

!!ReentrantLock的可重入体现

final boolean nonfairTryAcquire(int acquires) {  //ReentrantLock模式使用的是非公平锁,这样能提高系统的响应性能
    final Thread current = Thread.currentThread();
    int c = getState();  //获取资源的状态,
    if (c == 0) {     //为0就是别人还没有获取到锁,这个时候当前线程就可以获取到锁
        if (compareAndSetState(0, acquires)) { //用cas的方式获取到锁
            setExclusiveOwnerThread(current);  //这个方法里面就只有这一句  exclusiveOwnerThread = thread; 设置当前线程是独占线程
            return true;
        }
    }
    else if (current == getExclusiveOwnerThread()) {   //重点来了,这个方法就是主要判断是不是可重入的,如果之前的判断资源的状态是被上锁了,就会执行到这里,如果判断是本线程
        int nextc = c + acquires;  //把资源的的请求次数加1
        if (nextc < 0) // 当然也不是可以不限加的,如果超出的int的范围,抛出一个error的错误
            throw new Error("Maximum lock count exceeded");
        setState(nextc);  //设置资源状态
        return true;
    }
    return false;
}
总结:ReentrantLock可重入主要体现在current == getExclusiveOwnerThread()这个判断方法上面。如果是当前重入线程,资源状态添加
请求数,注意释放的时候也是要释放这个多次的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值