持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情
继承关系
Semaphore只实现了Serializable接口
public class Semaphore implements java.io.Serializable
内部类
Semaphore同样存在三个内部类,Sync、NonfairSync、FairSync,其中Sync继承了AQS,而NonfairSync和FairSync分别继承了Sync,所以从根本上来说Semaphore的实现还是依赖于AQS
abstract static class Sync extends AbstractQueuedSynchronizer{}
static final class NonfairSync extends Sync{}
static final class FairSync extends Sync
构造函数
创建具有给定许可数和非公平设置的信号量。 Semaphore(int permits)
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
Semaphore(int permits, boolean fair)
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}
核心函数 -- acquire
此方法从信号量获取一个(多个)许可,在提供一个许可前一直将线程阻塞,或者线程被中断
public void acquire() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
后续调用流程和CountDownLatch的调用流程一致,不在赘述 大致调用流程如下
核心函数 -- release
此方法释放一个(多个)许可,将其返回给信号量
public void release() {
sync.releaseShared(1);
}
后续调用流程和CountDownLatch的调用流程一致,不在赘述 大致调用流程如下
Semaphore示例
import java.util.concurrent.Semaphore;
class MyThread extends Thread {
private Semaphore semaphore;
public MyThread(String name, Semaphore semaphore) {
super(name);
this.semaphore = semaphore;
}
public void run() {
int count = 3;
System.out.println(Thread.currentThread().getName() + " trying to acquire");
try {
semaphore.acquire(count);
System.out.println(Thread.currentThread().getName() + " acquire successfully");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release(count);
System.out.println(Thread.currentThread().getName() + " release successfully");
}
}
}
public class SemaphoreDemo {
public final static int SEM_SIZE = 10;
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(SEM_SIZE);
MyThread t1 = new MyThread("t1", semaphore);
MyThread t2 = new MyThread("t2", semaphore);
t1.start();
t2.start();
int permits = 5;
System.out.println(Thread.currentThread().getName() + " trying to acquire");
try {
semaphore.acquire(permits);
System.out.println(Thread.currentThread().getName() + " acquire successfully");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
System.out.println(Thread.currentThread().getName() + " release successfully");
}
}
}