Semaphore使用方法
一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。
构造方法:
Semaphore(int permits)
创建具有给定的许可数和非公平的公平设置的 Semaphore。
Semaphore(int permits, boolean fair)
创建具有给定的许可数和给定的公平设置的 Semaphore。
主要方法:
release(int permits)
释放给定数目的许可,将其返回到信号量。
acquire()
从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。
示列1:
线程1会先执行完,然后释放两个线程
线程2和线程3会阻塞知道线程1执行release语句
Semaphore sph = new Semaphore(0); // 初始化释放几个线程
ExecutorService pool = new ThreadPoolExecutor(3, 3, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
pool.execute(new Thread() {
@Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
print();
sph.release(2);
}
});
pool.execute(new Thread() {
@Override
public void run() {
try {
sph.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
print();
}
});
pool.execute(new Thread() {
@Override
public void run() {
try {
sph.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
print();
}
});
}
private static void print() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().toString() + "*" + i);
}
}
示例2:控制一个方法最大同时线程访问数
public class SemaphoreTest {
static Semaphore semaphore = new Semaphore(5,true); // 最大线程数
public static void main(String[] args) {
for(int i=0;i<100;i++){
new Thread(new Runnable() {
@Override
public void run() {
test();
}
}).start();
}
}
public static void test(){
try {
//申请一个请求
semaphore.acquire(); // 如果线程超过5个,其他线程会阻塞到这来,知道线程执行结束释放许可
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"进来了");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"走了");
//释放一个请求
semaphore.release();
}
}
posted on 2019-05-08 20:37 COMPLEX-B 阅读(1721) 评论(0) 编辑 收藏 举报