接下來(lái)跟著上一篇, 解析情景七和情景八
情景七
寫(xiě)寫(xiě)讀
public static void main(String[] args) {
final Printer printer = new Printer();
Thread thread1 = new Thread(){
@Override
public void run() {
try {
printer.write("test1");
} catch (Exception e) {
e.printStackTrace();
}
}
};
Thread thread2 = new Thread(){
@Override
public void run() {
try {
printer.write("test2");
} catch (Exception e) {
e.printStackTrace();
}
}
};
Thread thread3 = new Thread(){
@Override
public void run() {
try {
printer.read("test3");
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread1.start();
thread2.start();
thread3.start();
}
首先線程1開(kāi)始
public void lock() {
sync.acquire(1);
}
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
protected final boolean tryAcquire(int acquires) {
// thread-0
Thread current = Thread.currentThread();
// c = 0
int c = getState();
// w = 0
int w = exclusiveCount(c);
// 不走此分支
if (c != 0) {
……
}
if (writerShouldBlock() ||
!compareAndSetState(c, c + acquires))
return false;
setExclusiveOwnerThread(current);
return true;
}
static final class FairSync extends Sync {
final boolean writerShouldBlock() {
return hasQueuedPredecessors();
}
}
public final boolean hasQueuedPredecessors() {
Node t = tail;
Node h = head;
Node s;
// 此時(shí)h和t都是null
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
說(shuō)明此時(shí)隊(duì)列中沒(méi)有被阻塞的線程, hasQueuedPredecessors返回false
接下來(lái)回到tryAcquire方法
protected final boolean tryAcquire(int acquires) {
// thread-0
Thread current = Thread.currentThread();
// c = 0
int c = getState();
// w = 0
int w = exclusiveCount(c);
// 不走此分支
if (c != 0) {
……
}
// writerShouldBlock返回false
// 不走此分支
if (writerShouldBlock() ||
!compareAndSetState(c, c + acquires))
return false;
// 設(shè)置獲得寫(xiě)鎖的線程為thread-0
setExclusiveOwnerThread(current);
return true;
}
此時(shí)線程1已經(jīng)獲取到鎖, 接下來(lái)線程2開(kāi)始執(zhí)行
// WriteLock
public void lock() {
sync.acquire(1);
}
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
protected final boolean tryAcquire(int acquires) {
// Thread-1
Thread current = Thread.currentThread();
// c = 1
int c = getState();
// w = 1
int w = exclusiveCount(c);
if (c != 0) {
// 由于加鎖線程為thread-0, 非當(dāng)前線程
// 進(jìn)此分支
if (w == 0 || current != getExclusiveOwnerThread())
return false;
......
}
......
}
回到acquire方法
public final void acquire(int arg) {
// 此時(shí)tryAcquire方法返回false
// 之后線程會(huì)緩存漁隊(duì)列中并阻塞自己
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
線程3開(kāi)始執(zhí)行
// ReadLock
public void lock() {
sync.acquireShared(1);
}
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
protected final int tryAcquireShared(int unused) {
// thread-2
Thread current = Thread.currentThread();
// c = 1
int c = getState();
// 由于已經(jīng)加寫(xiě)鎖, 所以exclusiveCount(c)為1
if (exclusiveCount(c) != 0 &&
// 并且加寫(xiě)鎖線程不是當(dāng)前線程
// 走此分支
getExclusiveOwnerThread() != current)
// 返回
return -1;
......
}
返回acquireShareShared
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
// 將該線程加入隊(duì)列中
// 并阻塞自己
doAcquireShared(arg);
}
情景八
寫(xiě)寫(xiě)寫(xiě)
所有經(jīng)歷的代碼都分析過(guò), 線程2和線程3都會(huì)被阻塞