AQS

来源:6-1 J.U.C之AQS-介绍

红邮筒

2019-01-13

老师,你在课中讲到“线程首先尝试获取锁,如果失败,把当前线程及等待状态等信息包成一个Node节点加入到之前的同步队列Sync queue,接着不断的循环尝试获取锁。但是,这个队列限制了只有当前节点head的直接后继节点才会尝试,head节点一般为获取锁的一个线程。线程获取锁如果失败了,会阻塞自己,直到被唤醒”,这一段有点不懂。
1、head节点是获取锁的线程?什么叫获取锁的线程?和它的后继节点功能一样吗?
2、前面说线程加入队列后,会不断尝试获取锁,后面又说获取锁失败,会阻塞,所以当获取锁失败后,是接着尝试,还是阻塞自己?

写回答

1回答

Jimin

2019-01-13

你好,这里涉及到课程里提到的那个同步队列,就是CLH队列,AQS同步器主要是通过CLH完成对线程的调度和状态的控制。这里的head节点是CLH队列的头节点,换句话说CLH其实属于一个链表结构,head节点是这个链表的表头,可以通过这个head节点找到所有后继节点。每个线程在尝试获取锁失败时,都会放入这个CLH队列的尾部。

AQS使用一个int类型的成员变量state来表示同步状态,当state>0时表示已经获取了锁,当state = 0时表示释放了锁。它提供了三个方法(getState()、setState(int newState)、compareAndSetState(int expect,int update))来对同步状态state进行操作,AQS可以确保对state的操作是安全的。进入CLH队列的线程,会阻塞当前线程,当同步状态释放时,则会把节点中的线程唤醒,使其再次尝试获取同步状态

0
2
Jimin
head节点相对其他节点,就只是为了让同步器能找到阻塞线程的存储位置,而且只存储这一个节点就足以找到其他阻塞线程的节点,其他和非head节点没什么不同。 这里说的阻塞是clh队列里节点对应的线程阻塞,本身就是因为获取不到锁才被放入队列里的,而且只要其他线程有释放锁,同步器可以通过变量的状态变化唤醒线程去争夺锁,同步状态。通过这种方式,同步器完成对线程状态的同步及控制
2019-01-13
共2条回复

Java高并发编程,构建并发知识体系,提升面试成功率

构建完整并发与高并发知识体系,倍增高薪面试成功率!

3923 学习 · 832 问题

查看课程