pattern block模块(AQS之CountDownLatchSammphoreReentrantLock等组件实现原理)
pattern block模块(AQS之CountDownLatchSammphoreReentrantLock等组件实现原理)如果你的一个线程启动了多个线程来执行一些任务,此时你的这个线程需要同步阻塞等待那些线程都执行完毕了,才可以继续往下走,此时可以用CountDownLatch。3、读锁加读锁,是不互斥的,读写锁是互斥的。一旦被unpark唤醒之后,就会在这里park的位置苏醒过来,重新进入一个for循环里面尝试加锁,加锁成功后,将上一个节点的p.next设置为null,也就是不指向自己,这里设置为null后,会被GC给垃圾回收。1、readWriteLock.writeLock().lock();如果是写锁:进去之后,当前没有排队的锁,就直接加写锁,如果当前state不等于0,就是有人加过写锁,如果是当前前程,是重入锁,就state加1,如果不是当前线程,就会返回false 进入等待队例,也就是写锁会和ReentractLock的加锁原理是一样的。只是这里会用32位的低16位做为写锁,高16位做为读锁进行计
ReentractLock1、加锁:当我们通过reentrantLock.lock();来加锁时,通过compareAndSetState来对state进行操作,结果成功了就得到了锁,用的CAS线程安全方式。如果没成功,判断线程标记是否是当前线程,如果是表示重入锁,对state进行加1,如果不是,放入等待队列,park挂起当前线程。
默认是非公平锁,也就是别人在排队,但是当线程释放锁的时候,刚好有一个线程在执行compareAndSetState,结果成功了就得到了锁。实现公平锁,只需要new ReentractLock(true);就可实现公平,原理是每次在执行compareAndSetState加锁的时候,都要先判断一下,如果前面没有排队等待的线程的话,就尝试加锁,否则是不能尝试加锁,直接入队阻塞等待。
2、释放锁:当我们通过reentrantLock.unlock();来释放锁时,先拿到state-1 得到一个值,然后判断释放锁的是否是当前线程,如果不是报错,是的话判断state是否等于0,如果是重入锁的话不等于0,些时只需要设置一下state的值就可以,然后如果等于0,就设置state的值为0,并且unpark释放自己next等待的线程,处理park的线程会被唤醒继续执行。
3、队头的元素唤醒之后是如何重新尝试加锁的呢?
一旦被unpark唤醒之后,就会在这里park的位置苏醒过来,重新进入一个for循环里面尝试加锁,加锁成功后,将上一个节点的p.next设置为null,也就是不指向自己,这里设置为null后,会被GC给垃圾回收。
1、readWriteLock.writeLock().lock();如果是写锁:进去之后,当前没有排队的锁,就直接加写锁,如果当前state不等于0,就是有人加过写锁,如果是当前前程,是重入锁,就state加1,如果不是当前线程,就会返回false 进入等待队例,也就是写锁会和ReentractLock的加锁原理是一样的。只是这里会用32位的低16位做为写锁,高16位做为读锁进行计数exclusiveCount。
2、readWriteLock.readLock().lock();如果是读锁:先进入判断当前exclusiveCount是否为不等于0,也就是有没有别的线程加过写锁,如果不等于0了,并且不是当前线程,那返回-1;然后将线程加入等待队列并挂起。
3、读锁加读锁,是不互斥的,读写锁是互斥的。
CountDownLatch如果你的一个线程启动了多个线程来执行一些任务,此时你的这个线程需要同步阻塞等待那些线程都执行完毕了,才可以继续往下走,此时可以用CountDownLatch。
CountDownLatch latch = new CountDownLatch(2);//首先设置AQS里面的state大小等于2
latch.countDown();//执行操作,判断state是否为0,如果为0,唤醒等待队例。不为0并CAS操作对state-1。
latch.await();//判断state是否小于等于0,如果不是,加入等待队例将main线程封装为一个node,加入AQS的等待队列,调用LockSupport.park()操作,挂起main线程。
(1)await(),触发了一个线程入队阻塞等待
(2)countDown(),如果state==0,唤醒队列里等待的所有的线程。
(3)所有线程被唤醒,发现state==0,就从await()方法里退出。
Semaphore等待指定数量的线程完成任务即可
常用的讲解结束,AQS中还有如Condition、CyclicBarrier、Exchanger等相关组件使用原理,如需要,可私信获取。
下节讲解:JVM相关技术点。