共计 899 个字符,预计需要花费 3 分钟才能阅读完成。
在 java 的锁机制中,偏心和非偏心的参考物是什么,集体而言感觉是绝对产生的后果而立,
简略的来说,如果一个线程组里,能保障每个线程都能拿到锁,那么这个锁就是偏心锁。
相同,如果保障不了每个线程都能拿到锁,也就是存在有线程饿死,那么这个锁就是非偏心锁。
本文围绕 ReenTrantLock 来讲。
实现原理
那如何能保障每个线程都能拿到锁呢,队列 FIFO 是一个完满的解决方案,也就是先进先出,java 的 ReenTrantLock 也就是用队列实现的偏心锁和非偏心锁。
在偏心的锁中,如果有另一个线程持有锁或者有其余线程在期待队列中期待这个所,那么新收回的申请的线程将被放入到队列中。
而非偏心锁上,只有当锁被某个线程持有时,新发出请求的线程才会被放入队列中(此时和偏心锁是一样的)。
所以,它们的差异在于非偏心锁会有更多的机会去抢占锁。
偏心锁:
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);
return true;
}
}
hasQueuedPredecessors 的实现
public final boolean hasQueuedPredecessors() {
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
非偏心锁:
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);
return true;
}
}
本文由猿必过 YBG 公布
正文完