请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

AQS

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

正在回答 回答被采纳积分+3

1回答

Jimin 2019-01-13 15:35:24

你好,这里涉及到课程里提到的那个同步队列,就是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 回复 有任何疑惑可以回复我~
  • 提问者 红邮筒 #1
    1、所以说head节点也是尝试获取锁失败后被放入CLH队列的线程?那么“这个队列限制了只有当前节点head的直接后继节点才会尝试”是为什么呢?head节点对应的这个线程为什么不接着尝试获取锁呢?
    2、进入CLH队列的线程不是获取锁失败的线程吗?它为什么会阻塞当前线程?当前线程又是什么?
    回复 有任何疑惑可以回复我~ 2019-01-13 15:50:24
  • Jimin #2
    head节点相对其他节点,就只是为了让同步器能找到阻塞线程的存储位置,而且只存储这一个节点就足以找到其他阻塞线程的节点,其他和非head节点没什么不同。
    
    这里说的阻塞是clh队列里节点对应的线程阻塞,本身就是因为获取不到锁才被放入队列里的,而且只要其他线程有释放锁,同步器可以通过变量的状态变化唤醒线程去争夺锁,同步状态。通过这种方式,同步器完成对线程状态的同步及控制
    回复 有任何疑惑可以回复我~ 2019-01-13 22:03:34
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信