首页>JAVA>正文

【上海Java培训】信号量(Semaphore)浅析

时间:2018-02-06 15:34:19   来源:上海尚学堂   阅读:
Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。信号量, 广义上说,信号量是锁的扩展,无论内部锁Synchronized和重写锁ReentrantLock一次都只允许一个线程访问一个资源,而信号量却可以指定多个线程,同时访问贡献资源。
 


                                                (图片来源于网络)

构造器

构造方法摘要
Semaphore(int permits) 
          创建具有给定的许可数和非公平的公平设置的 Semaphore。
 
Semaphore(int permits, boolean fair) 
          创建具有给定的许可数和给定的公平设置的 Semaphore。
 
 
在构造器信号对象时,必须要指定信号量的准入量,即同时能申请多少个许可。当每个线程每次只能申请一个许可时,相当于指定了同时有多少个线程可以访问共享资源。
 
方法摘要
 void acquire() 
          从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断
 void acquire(int permits) 
          从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞,或者线程已被中断
 void acquireUninterruptibly() 
   从此信号量中获取许可,在有可用的许可前将其阻塞。
 boolean tryAcquire() 
   仅在调用时此信号量存在一个可用许可,才从信号量获取许可。
 boolean tryAcquire(long timeout, TimeUnit unit) 
  如果在给定的等待时间内,此信号量有可用的许可并且当前线程未被中断,则从此信号量获取一个许可。
 void release() 
  释放一个许可,将其返回给信号量。
 
acquire()方法尝试获得一个准入许可,若无法获的,则线程会等待,直到有线程释放一个许可或者当前线程被中断。acquireUninterruptibly() 方法和acquire() 方法类似,但是不响应中断。
tryAcquire() 尝试获得一个许可,获取不成功时,不会出现线程等待。
 
 
Jdk 的官方javadoc 简单示例
/**
 * 上海尚学堂 shsxt.com
 * Semaphore 信号量
*/
public class SemaphoreDemo implements Runnable {
final Semaphore semp = new Semaphore(5);
@Override
public void run() {
try {
semp.acquire();
// 模拟耗时操作
Thread.sleep(2000);
System.out.println(Thread.currentThread().getId() + " : done !");
semp.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(20);
SemaphoreDemo demo = new SemaphoreDemo();
for (int i = 0; i < 20; i++) {
exec.submit(demo);
}
exec.shutdown();
}
}
 
小结:申明一个包含5个许可的信号量,意味同时可以有5个线程进入代码,申请信号量使用acquire() 操作,在离开时release () 释放信号量(务必)。

如果申请了没有释放则会造成信号量泄露问题,则进去临界区的量越来越少。直到所有的线程不能访问。

上海Java培训感谢您的阅读,转载请注明出处,后续Java相关技术文章奉上,请多关注!


分享:0

电话咨询

客服热线服务时间

周一至周五 9:00-21:00

周六至周日 9:00-18:00

咨询电话

021-67690939
15201841284

微信扫一扫