一 Semaphore
- 初始化并发数,允许最多多少个线程对共享资源访问。
- 实例化,默认非公平模式
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}
-
class Sync extends AbstractQueuedSynchronizer
控制并发,使用共享锁。
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 1192457210091910933L;
Sync(int permits) {//初始化共享锁数量
setState(permits);
}
final int getPermits() {
return getState();
}
final int nonfairTryAcquireShared(int acquires) {
for (;;) {//尝试获取锁,失败返回负数或成功返回正整数剩余锁数量
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
protected final boolean tryReleaseShared(int releases) {
for (;;) {//释放共享锁
int current = getState();
int next = current + releases;
if (next < current) // overflow
throw new Error("Maximum permit count exceeded");
if (compareAndSetState(current, next))
return true;//cas修改直到修改成功
}
}
final void reducePermits(int reductions) {
for (;;) {//减少共享锁数量,直到成功
int current = getState();
int next = current - reductions;
if (next > current) // underflow
throw new Error("Permit count underflow");
if (compareAndSetState(current, next))
return;
}
}
final int drainPermits() {
for (;;) {//清空共享锁,获取剩余锁数量
int current = getState();
if (current == 0 || compareAndSetState(current, 0))
return current;
}
}
}
- 非公平锁,即tryAcquireShared()都会先尝试获取一次获取锁。
static final class NonfairSync extends Sync {
private static final long serialVersionUID = -2694183684443567898L;
NonfairSync(int permits) {
super(permits);
}
protected int tryAcquireShared(int acquires) {
return nonfairTryAcquireShared(acquires);
}
}
- 公平锁,先判断是否是等待锁链表第一个节点,是第一个才尝试获取共享锁,否则在队列中按先后顺序获取。
static final class FairSync extends Sync {
private static final long serialVersionUID = 2014338818796000944L;
FairSync(int permits) {
super(permits);
}
protected int tryAcquireShared(int acquires) {
for (;;) {
if (hasQueuedPredecessors())
return -1;
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
}
二 CopyOnWriteArrayList
-
private transient volatile Object[] array;
存储数据
- get()函数直接按索引获取数组数据
- 变更的操作都是加锁后,分配新的数组,拷贝原数组到新数组中。
- add(),加锁控制添加元素
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();//加锁
try {
Object[] elements = getArray();
int len = elements.length;
//新分配数组,拷贝元素到新数组中,赋值新增元素
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);//更新存储的数组为新数组
return true;//返回true
} finally {
lock.unlock();
}
}
public E set(int index, E element) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
E oldValue = get(elements, index);
if (oldValue != element) {//更新数据
int len = elements.length;
//新分配数组,拷贝数据
Object[] newElements = Arrays.copyOf(elements, len);
newElements[index] = element;//修改数据
setArray(newElements);//更新保存数据数组
} else {
// Not quite a no-op; ensures volatile write semantics
setArray(elements);
}
return oldValue;
} finally {
lock.unlock();
}
}
三 CopyOnWriteArraySet
- 使用CopyOnWriteArrayList存储数组
- 对存储数据做唯一性处理
网友评论