/*
* ----------------------------------------------------
* 使用LockSupport来实现
* 使用park,unpark实现基本线程控制方法,更底层
* 没有必要的话,不要用这样的方式来控制线程,这里仅是做个试验
* ----------------------------------------------------
*/
class LockSupportSema implements IMySemaphore {
private AtomicInteger _iSignal;
private final int _iPermits;
private Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread> ();
LockSupportSema(final int i) {
_iSignal = new AtomicInteger(0);
_iPermits = i;
}
public void acquire() throws InterruptedException {
boolean wasInterrupted = false;
Thread current = Thread.currentThread();
waiters.add(current);
int i, update;
while (true) {
i = _iSignal.get();
if (waiters.peek() != current || (!wasInterrupted && (i >= _iPermits))) {
// 阻塞本线程
LockSupport.park(this);
if (Thread.interrupted()) {
wasInterrupted = true;
continue;
}
}
if (wasInterrupted) {
break;
}
if (i >= _iPermits) {
continue;
}
// 利用 AtomicInteger 的 CAS 方法
update = i + 1;
if (waiters.peek() == current && _iSignal.compareAndSet(i, update)) {
break;
}
}
// 唤醒下一个
waiters.remove();
LockSupport.unpark(waiters.peek());
if (wasInterrupted) {
throw new InterruptedException();
}
}
public void release() {
_iSignal.decrementAndGet();
LockSupport.unpark(waiters.peek());
}
} // END: LockSupportSema
体验 Java 并发 api,用不同方式实现信号量锁(Semaphore)(6)
最新推荐文章于 2022-09-08 15:24:50 发布