?? ?? ??本文是在AQS(AbstractQueuedSynchronizer)源代码分析(一)和AQS(AbstractQueuedSynchronizer)源代码分析(二)两篇文章的基础上编写的。关于shouldParkAfterFailedAcquire,addWaiter,parkAndCheckInterrupt,park,unpark,unparkSuccessor方法,如果不清楚,可以参考前两篇文章,本文不再做说明。
?? ?? ??AQS中的非共享模式与共享模式的区别在于,非共享模式每次只能有一个线程执行被锁定的内容,即目标语句或者目标方法。semaphore比如ReentrantLock类,在lock方法锁定的范围内,只会同时有一个线程在执行。而共享模式则是可以多个线程同时执行被锁定内容的。典型的应用类就是Semaphore。在设定初始信号量的值之后,比如是5;那么就会有五个线程同时执行。semaphore????
??一、共享的acquire方法
public final void acquireShared(int arg) {
//这个方法由子类实现。这里使用Semaphore.NonfairSync类中的tryAcquireShared进行说明
if (tryAcquireShared(arg) < 0)
//返回值小于0,则表示sate值已经被使用完,即已经有5个线程在运行。其他线程不能再进入了
doAcquireShared(arg);
}
//类Semaphore.NonfairSync
protected int tryAcquireShared(int acquires) {
return nonfairTryAcquireShared(acquires);
}
final int nonfairTryAcquireShared(int acquires) {
/**
* 当使用Semaphore时会有如下的代码:
* Semaphore semaphore = new Semaphore(5);
* semaphore.acquire();
* ……
* semaphore.release();
*
* 这里的getSate,如果是第一次进行semaphore.acquire()的话,
* getSate返回5,即我们设定的初始值
* 每一次semaphore.acquire()都会对将getSate的返回值进行减少,
* 即:int remaining = available - acquires,这段代码的含义
*/
for (;;) {
int available = getState(); //获取sate状态
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining; //这里会返回本次acquire之后,还剩余的sate值
}
}
上面的代码演示了Semaphore是如何进行信号量的获取操作的。当信号量获取失败之后,就会执行doAcquireShared(arg)方法。看一下doAcquireShared(arg)方法的代码:
private void doAcquireShared(int arg) {
final Node node = addWaiter(Node.SHARED); //向队列增加节点,追加的node是共享模式的node
boolean failed = true;
try {
boolean interrupted = false;
for (;;) { //死循环
final Node p = node.predecessor(); //获取当前节点的prevNode
if (p == head) {
int r = tryAcquireShared(arg); //如果是prevNode节点如果是head节点,则再次尝试acquire
if (r >= 0) {
setHeadAndPropagate(node, r); //再次尝试,获取成功
p.next = null; // help GC
if (interrupted)
selfInterrupt();
failed = false;
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) && //再次尝试,获取失败,挂起线程。可以参考前两篇文章
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-75627-1.html
票已买好
不管击沉撞沉拦截还是其他方法一定要强硬