利用aqs实现ReentrantLock/CountDownLatch/Semphore
ReentrantLock:lock state 0-> 1成功则获取锁,否则阻塞,获取锁的线程unlock state 1 -> 0,唤醒其他线程
CountDownLatch:awit,获取共享锁,如果state!=0,没获得锁,阻塞等待,countdown释放锁,state-1,如果state-1成功,判断如果state==0,则释放锁,唤醒阻塞线程
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
protected boolean tryReleaseShared(int releases) {
// Decrement count; signal when transition to zero
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
// 减一不成功,则再次循环
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
Semphore:acquire获取共享锁,state-1,如果<=0,没获得锁,则阻塞
public void acquire(int permits) throws InterruptedException {
if (permits < 0) throw new IllegalArgumentException();
sync.acquireSharedInterruptibly(permits);
}
public boolean tryAcquire(int permits) {
if (permits < 0) throw new IllegalArgumentException();
return sync.nonfairTryAcquireShared(permits) >= 0;
}
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;
}
}
独占的锁,一般只能由获取锁的线程释放
锁:
共享锁:读锁,java读写锁
独占锁:写锁
mysql:
读锁又称为共享锁
,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。select … lock in share mode
写锁又称为排他锁
,简称X锁,顾名思义,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
ConcurrentLinkedQueue
不阻塞,自循环、链表实现
LinkedBlockingQueue
阻塞,生产者-消费者模型、链表实现
ArrayBlockingQueue
阻塞,生产者-消费者模型、数组实现
PriorityBlockingQueue
带优先级的无界阻塞队列、最小堆
DelayQueue
利用PriorityBlockingQueue,最快到期的先出