ReentrantLock和Synchronized区别,公平锁和非公平锁区别

编程入门 行业动态 更新时间:2024-10-06 23:15:40

ReentrantLock和Synchronized区别,<a href=https://www.elefans.com/category/jswz/34/1754813.html style=公平锁和非公平锁区别"/>

ReentrantLock和Synchronized区别,公平锁和非公平锁区别

1 ReentrantLock和synchronized区别

  (1) synchronized 是Java的一个内置关键字,而ReentrantLock是Java的一个类。
  (2) synchronized只能是非公平锁。而ReentrantLock可以实现公平锁和非公平锁两种。
  (3) synchronized不能中断一个等待锁的线程,而Lock可以中断一个试图获取锁的线程。
  (4) synchronized不能设置超时,而Lock可以设置超时。
  (5) synchronized会自动释放锁,而ReentrantLock不会自动释放锁,必须手动释放,否则可能会导致死锁。

2 公平锁和非公平锁的区别

  公平锁的获取锁的过程:

 

static final class FairSync extends Sync {final void lock() { // 1 注意对比公平锁和非公平锁的这个方法acquire(1);}public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();}protected final boolean tryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {// 2 和非公平锁相比,这里多了一个判断:是否有线程在等待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;}
}

  非公平锁的获取锁的过程:

 

static final class NonfairSync extends Sync {final void lock() {//  1 和公平锁相比,这里会直接先进行一次CAS,如果当前正好没有线程持有锁,// 如果成功获取锁就直接返回了,就不用像公平锁那样一定要进行后续判断if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);}public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();}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) {// 2 这里没有对阻塞队列进行判断if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0) // overflowthrow new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;
}

  从源码上看,可以看到公平锁和非公平锁的两个区别:

(1) 线程在获取锁调用lock()时,非公平锁首先会进行一次CAS尝试抢锁,如果此时没有线程持有锁或者正好此刻有线程执行完释放了锁(state == 0),那么如果CAS成功则直接占用锁返回。
(2) 如果非公平锁在上一步获取锁失败了,那么就会进入nonfairTryAcquire(int acquires),在该方法里,如果state的值为0,表示当前没有线程占用锁或者刚好有线程释放了锁,那么就会CAS抢锁,如果抢成功了,就直接返回了,不管是不是有其他线程早就到了在阻塞队列中等待锁了。而公平锁在这里抢到锁了,会判断阻塞队列是不是空的,毕竟要公平就要讲先来后到,如果发现阻塞队列不为空,表示队列中早有其他线程在等待了,那么公平锁情况下线程会乖乖排到阻塞队列的末尾。
  如果非公平锁 (1)(2) 都失败了,那么剩下的过程就和非公平锁一样了。
(3) 从(1)(2) 可以看出,非公平锁可能导致线程饥饿,但是非公平锁的效率要高。

更多推荐

ReentrantLock和Synchronized区别,公平锁和非公平锁区别

本文发布于:2024-02-25 07:58:54,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1698301.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:公平   区别   ReentrantLock   Synchronized

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!