AQS理解之六,AQS的其他实现类

AQS理解之六,AQS的其他实现类

1,ThreadPoolExecutor 中的 Worker 类

protected boolean tryAcquire(int unused) {if (compareAndSetState(0, 1)) {setExclusiveOwnerThread(Thread.currentThread());return true;}return false;}protected boolean tryRelease(int unused) {setExclusiveOwnerThread(null);setState(0);return true;}public void lock()        { acquire(1); }public boolean tryLock()  { return tryAcquire(1); }public void unlock()      { release(1); }public boolean isLocked() { return isHeldExclusively(); }

重写了这几个方法,可以看出来实现的是一个不可重入的锁。

2,Semaphore 信号量类

abstract static class Sync extends AbstractQueuedSynchronizer {private static final long serialVersionUID = 1192457210091910933L;Sync(int permits) {setState(permits);}final int getPermits() {return getState();}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) // overflowthrow new Error("Maximum permit count exceeded");if (compareAndSetState(current, next))return true;}}final void reducePermits(int reductions) {for (;;) {int current = getState();int next = current - reductions;if (next > current) // underflowthrow new Error("Permit count underflow");if (compareAndSetState(current, next))return;}}final int drainPermits() {for (;;) {int current = getState();if (current == 0 || compareAndSetState(current, 0))return current;}}
}

使用state的数量来代表信号量已经使用的数,如果大于0,则可以进入,如果小于等于0,则阻塞住,不能获取到信号量。

和ReentrantLock有点类似,如果acquire时不能进入,则阻塞,并加入链表,在release时会将阻塞的节点unpark打开。

3,CountDownLatch

首先看下CountDownLatch的构造使用

CountDownLatch countDownLatch = new CountDownLatch(5);//构造
countDownLatch.countDown();//计数
countDownLatch.await();//等待完成
//构造时,实际上是设置了state为一个数。
Sync(int count) {setState(count);
}
//这里实际上就是一个release操作,每次都会将state原子性减一,并顺便会将阻塞的节点unpark打开。
public final boolean releaseShared(int arg) {if (tryReleaseShared(arg)) {doReleaseShared();return true;}return false;
}protected boolean tryReleaseShared(int releases) {// Decrement count; signal when transition to zerofor (;;) {int c = getState();if (c == 0)return false;int nextc = c-1;if (compareAndSetState(c, nextc))return nextc == 0;}}//await方法实际上是计算state是否为0,如果不为0,则park阻塞等待直到为0
public final void acquireSharedInterruptibly(int arg)throws InterruptedException {if (Thread.interrupted())throw new InterruptedException();if (tryAcquireShared(arg) < 0)doAcquireSharedInterruptibly(arg);
}protected int tryAcquireShared(int acquires) {return (getState() == 0) ? 1 : -1;}

使用state表示仍需要执行的次数,当为0时结束阻塞

总结

AQS实现了一套公共的实现Java锁的逻辑,我们可以继承它来实现自己在多线程下的锁。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部