信号量是对锁的扩展。无论是内部锁synchronized还是重入锁ReentrantLock,一次都只允许一个线程访问某个临界资源。但信号量可以指定多个线程,同时访问某个临界资源。
//信号量的构造函数
public Semaphore(int permits) //指定信号量的准入数,即同时能申请多少个许可
//当一个线程每次只申请一个许可时,这就相当于指定了同时最多有多少个线程可以访问这个资源
public Semaphore(int permits,boolean fair) //第二个参数可以指定是否公平
//信号量的主要逻辑方法
//尝试获得一个准入的许可,若无法获得则线程等待;直到有线其他程释放许可或该线程被中断
public void acquire()
//与上类似,但不响应中断
public void acquireUninterruptibly()
//尝试获得一个许可,成功则返回true;否则返回false,不会等待;
public boolean tryAcquire()
public boolean tryAcquire(long timeout,TimeUnit unit)
//释放许可
public void release()
//示例代码
public class SemapDemo implements Runnable{
//同时有5个线程可以进入临界区
final Semaphore semaphore = new Semaphore(5);
@Override
public void run() {
try {
semaphore.acquire(); //申请信号量
Thread.sleep(2000); //模拟耗时操作
System.out.println(Thread.currentThread().getId()+":done!");
semaphore.release(); //释放信号量
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//线程池
ExecutorService executorService = Executors.newFixedThreadPool(20);
final SemapDemo demo = new SemapDemo();
for (int i = 0; i < 20; i++) {
executorService.submit(demo);
}
}
}