ReentrantLock 重入锁, ReadWriteLock 读写锁

ReentrantLock: 就是支持重进入的锁,他表示该锁 能够支持一个线程对资源的重复加锁.除此之外,该锁还支持获取锁时的公平性和非公平性选择;

(一)重进入:

是指任意线程在获取到锁之后能够再次获取该锁而不会被锁阻塞,该特性实现需解决两个问题:

(1)线程再次获取锁-->.锁需要去识别获取锁的线程是否是当前线程,如果是,则再次获取成功.

(2)锁的最终释放:-->线程重复n次获取了锁,随后在第n次释放锁之后,其他线程能够获取到该锁.锁中包含一个计数器,当获取锁时+1,当释放锁时-1,当基数为0时,可以释放该锁,其他线程可以能够获取锁对象;

ReentrantLock:lock();

FairSync:lock();

AbstractQueuedSynchronizer:acquires(int args);

 final void lock() {
            acquire(1);
  }

  protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            //获取当前aqs的状态,如果是0,表示当前还没有线程来占有
            int c = getState();
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    //当前线程获取 aqs 成功,将aqs中的 exclusiveThread(独占线程)  设置为当前的限制
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            //如果之前的 在aqs中的独占线程和当前的线程相同,那么就将state+1;当释放线程的时候  是-1一个个释放,直到state为0时候,才完全释放
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }

 

当获取锁失败之后:

 acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
    
  //将当前线程设置成一个node,在aqs中以链表的形势存放,然后根据链表一个个获取锁,
  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;
    }
    
    
    //当前线程  阻塞
     selfInterrupt();
     static void selfInterrupt() {
        Thread.currentThread().interrupt();
    }

(二)公平与非公平获取锁的区别:

公平性:公平性与否是针对获取锁而言,如果一个锁时公平的,那么锁获取的顺序就应该符合请求的绝对的时间顺序,也就是FIFO.[1,2,3,4] 获取锁的顺序依次是 1,2,3,4

非公平性: 锁在获取的过程中,一个线程可能多次获取锁,刚释放的线程再次获取同步状态(当一个线程请求一个锁时,只要获取了同步状态,即成功获取了锁)的几率非常大,使得其他线程只能在同步状态下等待. [1,2,3,1,4,6] --> 输出则是:1,1,2,3,4,6

ReadWriteLock: 大部分锁都是排他锁,这些锁在同一时刻只能允许一个线程进行访问,而读写锁在同一时刻可以允许多个线程同时访问,但是在写线程的时候,其他写线程和读线程将会被阻塞.读写锁维护了一个锁,一个读锁和写锁.

转载于:https://my.oschina.net/u/3300098/blog/1363080

你可能感兴趣的:(ReentrantLock 重入锁, ReadWriteLock 读写锁)