import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreTest {
static Semaphore semaphore = new Semaphore(3);
static void task(int sec) {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " start state=" + semaphore.availablePermits());
TimeUnit.SECONDS.sleep(sec);
System.out.println(Thread.currentThread().getName() + " end state=" + semaphore.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
/**
* 信号量,分配n把共享锁
* 分配3把共享锁,也就设定state的值
* nonfairTryAcquireShared for 自旋,只有当 state分配完即小于0 或者 CAS更新成功,就返回剩余的state,
* 如果state小于0 就会执行中断doAcquireSharedInterruptibly(arg) 自旋等候,直到try 获取到共享锁为止
*/
/*
//核心方法 Semaphore Sync
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;
}
}
*/
public static void main(String[] args) {
new Thread(() -> task(2)).start();
new Thread(() -> task(2)).start();
new Thread(() -> task(6)).start();
new Thread(() -> task(2)).start();
new Thread(() -> task(2)).start();
}
}
输出:
Thread-0 start state=2
Thread-1 start state=1
Thread-2 start state=0
Thread-0 end state=0
Thread-1 end state=0
Thread-3 start state=1
Thread-4 start state=0
Thread-3 end state=0
Thread-4 end state=0
Thread-2 end state=2
Semaphore 的构造函数 是创建一个非公平锁
public class Semaphore implements java.io.Serializable {
...
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
...
}
每个线程执行task 都先获取锁 semaphore.acquire
public class Semaphore implements java.io.Serializable {
...
public void acquire() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
...
}
Semaphore 的内部类 Sync 继承了 AbstractQueuedSynchronizer。sync.acquireSharedInterruptibly(1); 是调父类AbstractQueuedSynchronizer的acquireSharedInterruptibly方法
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
...
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
}
...
}
tryAcquireShared(arg) 方法由AQS的子类Sync 的子类NonfairSync 实现
public class Semaphore implements java.io.Serializable {
...
static final class NonfairSync extends Sync {
private static final long serialVersionUID = -2694183684443567898L;
NonfairSync(int permits) {
super(permits);
}
protected int tryAcquireShared(int acquires) {
return nonfairTryAcquireShared(acquires);
}
}
...
}
nonfairTryAcquireShared 由 NonfairSync 的父类Sync实现。
nonfairTryAcquireShared for 自旋,只有当 state分配完即小于0 或者 CAS更新成功,就返回剩余的state。
public class Semaphore implements java.io.Serializable {
abstract static class Sync extends AbstractQueuedSynchronizer {
...
final int nonfairTryAcquireShared(int acquires) {
for (;;) {
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
...
}
如果state小于0 就会执行中断doAcquireSharedInterruptibly(arg) 自旋等候,直到try 获取到共享锁为止。
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
implements java.io.Serializable {
...
private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head) {
int r = tryAcquireShared(arg);
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // help GC
failed = false;
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
...
}