CAS:比较并交换。三个值参数,(地址值,期望值,新值),如果地址的值等于期望值就把地址值设置成新值,否则就循环,直到成功。这是一种乐观锁,底层通过cpu指令实现,在java的unsafe类中。引发问题:1.如果一直不成功(业务需要时间长),消耗cpu。2.ABA:问题,加版本号解决.3:适用范围小,只能使用在单个的基本变量(原子类)。
AQS
用于实现依赖先进先出(FIFO)等待队列的阻塞锁和相关同步器(信号量、事件等)。
state:表示同步状态,独占时值为1(可重入),共享时可是>=1;
cas:cas改变同步状态,同时也改变队列的情况(添加或删除节点),保证线程安全
valtaile:保证线程可见性
LockSupport.unpark(s.thread);通过lockSupport实现线程的阻塞和唤醒
可以关联多个Condition队列,用于线程通信。
node是线程封装的节点,节点共享同一个队列,节点用相关的属性表示节点的类型。
能够响应中断。
private transient volatile Node head;//等待队列的头,延迟初始化。
private transient volatile Node tail;//等待队列的尾部,延迟初始化。仅通过方法enq修改以添加新的等待节点。
private volatile int state;//同步状态。
//线程都会被封装成一个节点加入到队列中,节点有两种模式,共享和独占模式
static final class Node {
static final Node SHARED = new Node(); //共享模式,处于等待状态
static final Node EXCLUSIVE = null; //独占模式,处于等待
static final int CANCELLED = 1; //用于指示节点正在独占模式下等待的标记WaitStatus值,用于指示线程已取消。
static final int SIGNAL = -1;//waitStatus值,指示后续线程需要取消连接。
static final int CONDITION = -2;//waitStatus值,指示线程正在等待条件。
static final int PROPAGATE = -3;//waitStatus值,指示下一个acquireShared应无条件传播。
volatile int waitStatus;//等待状态
volatile Node prev;//前置节点,在取消前一个节点时,我们会在查找未取消的前一个节点时短路,该前一个节点将始终存在,因为头节点从未取消:只有成功获取后,节点才会成为头节点
volatile Node next;//后置节点,释放时将对其进行解析
volatile Thread thread;//封装的线程,使此节点排队的线程。构造时初始化,使用后为空。
Node nextWaiter;//
}
public class ConditionObject implements Condition, java.io.Serializable {
private static final long serialVersionUID = 1173984872572414699L;
private transient Node firstWaiter;//队头元素
private transient Node lastWaiter;//队尾元素
private static final int REINTERRUPT = 1;//意味着退出等待时重新中断
private static final int THROW_IE = -1;//意味着退出等待时抛出InterruptedException
}