自定義互斥鎖:
參考jdk的ReentrantLock可重入鎖源碼,定義一個互斥鎖。
因爲鎖是獨佔方式,所以重寫AQS的tryAcquire()、tryRelease()、isHeldExclusively()方法即可!
import org.jetbrains.annotations.NotNull;
import java.io.Serializable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
* @description: 自定義互斥鎖 共享資源(state)鎖狀態這裏只有兩種狀態:0-未被鎖定 1-鎖定
* @author: yangzihe(ys1405)
* @create: 2020-03-21 11:05
**/
public class MyMutexLock implements Lock, Serializable {
//自定義同步器
private static final class Sync extends AbstractQueuedSynchronizer {
//判斷當前線程是否正在獨佔資源,即鎖資源是否處於鎖定狀態
@Override
protected boolean isHeldExclusively() {
return getState() == 1;
}
//獲取鎖
@Override
protected boolean tryAcquire(int arg) {
assert arg == 1;//只可爲1
if (compareAndSetState(0, 1)) {//state爲0時設置爲1(CAS修改),無重入
setExclusiveOwnerThread(Thread.currentThread());//設置當前線程獨佔共享資源state
return true;
}
return false;
}
//釋放鎖
@Override
protected boolean tryRelease(int arg) {
assert arg == 1;//限定爲1
if (getState() == 0) {//當前線程得到的state=0,即未佔有鎖
throw new IllegalMonitorStateException();
}
setExclusiveOwnerThread(null);
setState(0);//釋放鎖
return true;
}
final ConditionObject newCondition() {
return new ConditionObject();
}
}
//同步類的實現都是依賴自定義的同步器。模板模式:調用AQS方法,底層調用的是重寫的方法
private final Sync sync = new Sync();
//獲取鎖對象,自旋等待,一直等到獲取成功才返回
@Override
public void lock() {
sync.acquire(1);//1:tryAcquire()的入參
}
//獲取鎖對象,可中斷
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
//嘗試獲取鎖
@Override
public boolean tryLock() {
return sync.tryAcquire(1);
}
//嘗試獲取鎖,過了time時間後放棄
@Override
public boolean tryLock(long time, @NotNull TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(time));
}
//釋放鎖
@Override
public void unlock() {
sync.release(1);
}
@NotNull
@Override
public Condition newCondition() {
return sync.newCondition();
}
}
jdk的CountDownLatch源碼筆記記錄:
public class CountDownLatch {
/**
* 繼承AQS的內部Sync同步器
*/
private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 4982264981922014374L;
//使用AQS的state來表示計數count.
Sync(int count) {
// 使用AQS的setState()方法設置狀態
setState(count);
}
int getCount() {
// 使用AQS的getState()方法獲取狀態
return getState();
}
// 重寫在共享模式下獲取鎖,count=0表所有需等待的線程執行完畢,獲取鎖成功,代碼可以繼續往下執行
protected int tryAcquireShared(int acquires) {
// 這裏用狀態state是否爲0來表示是否成功,爲0的時候可以獲取到返回1,否則不可以返回-1
return (getState() == 0) ? 1 : -1;
}
// 重寫在共享模式下釋放鎖
protected boolean tryReleaseShared(int releases) {
// 在for循環中Decrement count直至成功;
// 當狀態值即count爲0的時候,返回false表示 signal when transition to zero
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
//cas操作
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
}
private final Sync sync;
// 使用給定計數值構造CountDownLatch
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
// 讓當前線程阻塞直到計數count變爲0,或者線程被中斷
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
// 阻塞當前線程,除非count變爲0或者等待了timeout的時間。當count變爲0時,返回true
public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
// count遞減
public void countDown() {
sync.releaseShared(1);
}
// 獲取當前count值
public long getCount() {
return sync.getCount();
}
public String toString() {
return super.toString() + "[Count = " + sync.getCount() + "]";
}
}