java并发编程11-JUC
JUC
AQS
AbstractQueuedSynchronizer 是阻塞式的锁和相关的同步器工具的框架
ReentrantLock
如何重入
用一个变量记录重入了多少次 ### NonfairSync #### lock cas ,成功就吧ouner改为自己,否则acquire,把自己放进链表中 #### acquire tryacquire,成功就结束,失败的话还会尝试几次,然后才park,并为前驱标记,让前驱记得唤醒自己,如果曾经被打断的话,会被忽略,再次进入aqs队列,得到锁以后会打断自己来再次重新打断 #### unlock 调用release #### release 如果成功,unpark唤醒后继,为什么是非公平呢?因为被唤醒以后,可能会有不在链表中线程来跟自己竞争,所以这不公平 #### acquireInterruptibly 不忽略打断,抛出异常即可 ### FairSync 区别再也tryAccquire,如果c=0,即没人占用锁,他还会去检测AQS队列是否为空,其实就是看一下链表队列首部是否为自己,或者链表队列是否为空 ### Condition 条件变量又是一个链表,当我们调用await的时候,当前线程的节点会被放进其中,然后把节点状态设为CONDITION, #### fullrelease 拿到锁的重数,然后一次性释放,在唤醒后面的节点,然后park自己 #### signal 当调用的时候讲条件变量的链表中第一个元素取出并加入到锁的等待链表中。 ## ReentrantReadWriteLock - ReentrantReadWriteLock rw = new ReentrantReadWriteLock() - rw.readLock(); - rw.writeLock(); ### 锁升级 下面的代码会写锁永久等待 1
2rw.readLock().lock();
rw.writeLock().lock();1
2
3
4
5
6
7
8
9// 获得写锁
rw.writeLock().lock();
// 锁降级
rw.readLock().lock();
rw.writeLock().unlock();
// 获得读锁
rw.readLock().unlock();
cyclicbarrier
CountdownLatch 不能用多次,要多次用的话,只能反复创建才行。 await()即为CountdownLatch的countDown cyclicbarrier 构造的时候可以传进一个Runnable,当信号值降低为0的时候,运行Runnable,然后信号量再次赋值为n达到重用的效果 千万要注意nthreads和线程数要相等,不要搞骚操作,不是说不行,是不太好。