系列文章目录
目录
前言
本文总结学习并发知识需要用到的知识点,如:CAS 、AQS队列、公平锁、非公平锁等概念
一、CAS是什么?
CAS全称为:Compare and Swap,比较并交换。在Java中,CAS主要是由sun.misc.Unsafe这个类通过调用native方法实现。如下设置state所示:
protected final boolean compareAndSetState(int expect, int update) {
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
CAS有4个参数:当前对象、偏移量、预期值expect、要修改的新值update。如果当前对象this在内存中偏移量为offset位置的值等于预期值,则原子地将当前值设置为给定的更新值,否则什么都不做。该操作是一个原子操作,被广泛的应用在Java的底层实现中。
二、AQS是什么?
AQS全称为:AbstractQueuedSynchronizer 抽象队列同步器。
是一个用于构建锁和同步容器的框架。JUC包内许多类都是基于AQS构建,例如ReentrantLock,Semaphore,CountDownLatch,ReentrantReadWriteLock,FutureTask等。AQS解决了在实现同步容器时设计的大量细节问题。
AQS使用一个FIFO的队列表示排队等待锁的线程,队列头节点不与任何线程关联。其他的节点与等待线程关联,每个节点维护一个等待状态waitStatus。
三、
公平锁、非公平锁区别?
公平锁:如果同时有多个线程进来尝试获取,当它发现自己不是在队首的话,就会排到队尾,由队首的线程获取到锁。
- 缺点: 公平锁相比非公平锁效率低,队列里面除了第一个线程,其他的线程都会阻塞,cpu唤醒阻塞线程的开销会很大。
非公平锁:并非是先来先获取锁的,多个线程互相竞争获取锁;多个线程去获取锁的时候,会直接去尝试获取,获取不到,再去进入等待队列,如果能获取到,就直接获取到锁。
- 缺点:可能导致队列中间的线程一直获取不到锁或者长时间获取不到锁,导致锁饥饿。
四、可重入锁
可重入锁是指同一个线程可以多次获取同一把锁。ReentrantLock和synchronized都是可重入锁。
五、可中断锁
可中断锁是指线程尝试获取锁的过程中,是否可以响应中断。synchronized是不可中断锁,而ReentrantLock则提供了中断功能。
六、waitStatus
SIGNAL:此节点的后继被(或即将)阻塞(通过park),因此当前节点在释放或取消时必须unpark其后继节点。
CANCELLED:由于超时或中断,该节点被取消。节点永远不会离开这个状态。特别是,取消节点的线程永远不会再次阻塞。
CONDITION:该节点当前在条件队此处使用此值与该字段的其他用途无关,但简化了机制。) 列中。它在传输之前不会用作同步队列节点,此时状态将设置为 0。(
PROPAGATE:releaseShared 应该传播到其他节点。这在 doReleaseShared 中设置(仅适用于头节点)以确保传播继续,即使其他操作已经介入。
0:以上都不是
static final int CANCELLED = 1;
static final int SIGNAL = -1;
static final int CONDITION = -2;
static final int PROPAGATE = -3;
以上便是一些基础知识的总结,后续继续补充。