1.什么是AQS
是一个用于构建锁和同步容器的队列同步器,是整个JUC包下lock体系的核心。如ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore都是基于它来实现的,它解决了在实现同步容器时设计的大量细节问题,它的核心构成部分为:使用一个 先进先出的FIFO的队列存储排队等待锁的线程,使用一个用volatile修饰的int类型的state同步状态来记录当前是否有线程持有锁,0表示没有线程获得锁,1表示有,上锁state就加1,释放锁就对应减1,有重入锁现象,这个值就大于1,然后需要逐级去释放。
2.什么是cas?
cas就是乐观锁的一种实现方式
ABA问题:
1.线程1读取指定内存地址的数据A,加载到寄存器,此时读取出来的值不仅会作为要被计算的值A,还会作为比较值A
2.此时线程1的cpu被线程2抢占了,线程2也从同样的内存地址中读取了同样数据的A,线程2比线程1先执行完,线程2产生了新数据B
并且根据CAS原理把B存入该内存地址(内存的值由A被改为B)
3.还没完,线程2执行完成后,线程1又没抢到线程,此时cpu被线程3抢占,线程3读取到数据B,线程3比线程1先执行完,线程3产生了新数据A,值与一开始的A相等,但值相等就意味着相等,此时内存又从B变为A
4.这个时候线程1执行完了,根据cas原理存入数据,然后比较值A是原来的A,而执行内存中的A已经被替换了,但原A的值与内存中的A值是相等的,根据cas线程1会把新的执行结果存入内存地址,在实际业务,两个数的值相等,但这两个数并不是同一个数
解决方案:加个版本号,比较版本号
3.JUC下的工具类
CountdownLatch:利用他实现类似计数器的功能
Cyclicbarrier:通过它可以实现让一组线程等待至某个状态之后再全部同时执行
Simephore:信号量,Sem、aphore可以控同时访问的线程个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可