jdk 源码分析(7)java ReentrantLock结构
来源:互联网 发布:go语言编程 pdf 编辑:程序博客网 时间:2024/06/05 20:11
lock看上去很牛,其实真的很牛,如果你仔细研究代码发现,所以的lock都只是去争一个变量state
private volatile int state;
如果你能将这个state从零变成1,你就可以获得资源,
因为要判断是谁获得了这个state,所以需要保留这个线程的对象。
因为要记录有哪些线程在争论lock,所以需要队列,既然有队列,就有队列的机制,公平机制(先到先得),非公平机制(可能存在饿死的线程,一直得不到)。这里的队列是用Node组成的链表,记录了head和tail。
源码:
public ReentrantLock() { sync = new NonfairSync();}
默认采用非公平的机制。
对比公平和非公平:
非公平的lock 直接先去尝试获取一次线程,如果拿不到再去排队。
final void lock() {
//这里就是上面说的争的对象。
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
公平的,会直接去排队。
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;
}
对比非公平的就直接了当得多,从不在乎别人的感受
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
//没人用
if (c == 0) {
//那我用吧
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
//一家人
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
世事可能不如意,所以需要排队。在末尾添加。
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;
}
排队的用户怎么执行能,肯定在循环中,
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
到此结束。
问题:每个Node都有一个State吗?还是共用的呢。
阅读全文
0 0
- jdk 源码分析(7)java ReentrantLock结构
- ReentrantLock源码分析(JDK 1.7)
- java ReentrantLock源码分析
- JDK之ReentrantLock,AbstractQueuedSynchronizer源码分析
- Java并发-ReentrantLock源码分析
- java并发-ReentrantLock源码分析
- java并发-ReentrantLock源码分析
- java源码分析:重入锁ReentrantLock
- Java 并发 ---ReentrantLock源码分析
- jdk 源码分析(1)java hashmap的结构
- jdk 源码分析(4) java Set 结构
- jdk 源码分析(5)java ConcurrentSkipListMap结构
- jdk 源码分析(6)java BitSet结构
- JAVA 并发类(六) ReentrantLock 源码分析
- JAVA线程之ReentrantLock源码分析(一)
- JAVA线程之ReentrantLock源码分析(二)
- Java多线程系列(七)—ReentrantLock源码分析
- java ReentrantLock源码 分析 妥妥的
- perl 处理 回车 换行符
- 1102. Invert a Binary Tree (25)反转二叉树
- 一致性哈希算法简介:简单的自我理解 与 一些摘抄的资料
- 老人与流浪狗
- 并发服务器select
- jdk 源码分析(7)java ReentrantLock结构
- SpringBoot中Pageable的简单分页排序查询
- webservice
- Java / Android 基于Http的多线程下载的实现
- 设计模式之禅笔记--面向对象设计六大原则之一
- ArgumentError: invalid byte sequence in UTF-8 Use --trace for backtrace.
- 排序——归并排序
- RHEL7.4发布了
- 0和5(思维-水题)