Semaphore(信号量)
Synchronize与Lock的方式都是用于限制同一资源只允许一个线程访问,
而Semaphore 提供了多线程访问同一资源的方式
逻辑场景
如银行服务柜台有5个,每个柜台只允许服务一个客户,服务完成释放,继续
服务下一个客户。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
* 模块:【信号量】
* <p>
* 开发: Bruce.Liu By 2018/8/23 下午8:53 Create
*/
public class SemaphoreDemo implements Runnable {
//定义信号量为5
final Semaphore semap = new Semaphore(5);
@Override
public void run() {
try {
//尝试获取一个许可,若超过限制 如5,会进入等待
semap.acquire();
TimeUnit.SECONDS.sleep(1);
System.err.println("当前线程:"+Thread.currentThread().getName());
//释放、让出位置给其他线程
semap.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ExecutorService ex = Executors.newFixedThreadPool(20);
final SemaphoreDemo demo = new SemaphoreDemo();
for(int i = 0 ; i < 20 ; i++){
ex.submit(demo);
}
ex.shutdown();
}
}
代码解读
A. main函数创建了一个线程池为20的对象,
循环执行20次SemaphoreDemo对象
B. 每个一个子线程执行都会通过 semap.acquire();
去尝试获取一个许可,若超过限制 如5,会进入等待。
C. 通过semap.release()释放、让出位置给其他线程,
D. 由于都是TimeUnit.SECONDS.sleep(1);间隔一秒,
线程执行会以每5个为一个批次打印,其实semap.release()释放时
就会有一个线程被打印,只是释放与打印时间都是同瞬间。
参考:《实战 Java 高并发程序设计》这本书。
网友评论