Java并发编程信号量Semapher攻略
在Java并发编程中,信号量(Semaphore)是一种用于控制并发线程数量的工具,大多用于控制对共享资源的访问,通过信号量的控制,可以实现线程之间的协作与资源控制。
信号量(Semaphore)的概念及使用方法
信号量(Semaphore)是一个经典的多线程同步控制工具,它用于控制同时访问某个资源的线程数量,通过指定信号量的许可数量,我们可以控制同时访问共享资源的线程数量。
具体来说,Semaphore可以分为两种类型:
- 二元信号量(Binary Semaphore):只具有两种状态,1表示可用,0表示不可用,通常将其用于控制对临界区的访问;
- 计数信号量(Counting Semaphore):具有一定数量的状态,我们可以通过调用release()方法增加信号量,调用acquire()方法减少信号量。
Semaphore的使用方法如下:
Semaphore sem = new Semaphore(permits); // 构造Semaphore对象,permits表示初始信号量的数量
sem.acquire(); // 获取信号量,如果信号量不够的话就一直等待
...
sem.release(); // 释放信号量
示例一:Semaphore控制线程并发访问
下面的示例用两个线程并发访问同一个共享资源,通过Semaphore控制线程的并发访问数量:
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(2); // 构造Semaphore对象,permit数量为2
ExecutorService executorService = Executors.newCachedThreadPool(); // 构造线程池
for (int i = 1; i <= 10; i++) { // 启动10个线程
executorService.execute(() -> {
try {
semaphore.acquire(); // 获取Semaphore许可
System.out.println(Thread.currentThread().getName()+" got the permit.");
Thread.sleep(2000); // 等待2s
semaphore.release(); // 释放Semaphore许可
System.out.println(Thread.currentThread().getName()+" released the permit.");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executorService.shutdown(); // 关闭线程池
}
}
运行结果如下:
pool-1-thread-1 got the permit.
pool-1-thread-2 got the permit.
pool-1-thread-1 released the permit.
pool-1-thread-3 got the permit.
pool-1-thread-2 released the permit.
pool-1-thread-4 got the permit.
pool-1-thread-3 released the permit.
pool-1-thread-5 got the permit.
pool-1-thread-4 released the permit.
pool-1-thread-6 got the permit.
pool-1-thread-5 released the permit.
pool-1-thread-7 got the permit.
pool-1-thread-6 released the permit.
pool-1-thread-8 got the permit.
pool-1-thread-7 released the permit.
pool-1-thread-10 got the permit.
pool-1-thread-9 got the permit.
pool-1-thread-10 released the permit.
pool-1-thread-9 released the permit.
可以看到,在Semaphore的控制下,每次只有两个线程能够同时访问共享资源,其他线程需要等待已经获取许可的线程释放许可后才能继续执行。
示例二:Semaphore模拟停车场
下面的示例用Semaphore模拟停车场系统,停车场只允许有限数量的车辆进入,超过限制的车辆需要等待其他车辆驶离后才能进入:
public class SemaphoreParkingDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(2); // 停车场只能同时容纳2辆汽车
ExecutorService executorService = Executors.newCachedThreadPool(); // 构造线程池
for (int i = 1; i <= 5; i++) { // 启动5辆汽车
executorService.execute(() -> {
try {
semaphore.acquire(); // 获取Semaphore许可
System.out.println(Thread.currentThread().getName() + " 进入了停车场。");
Thread.sleep(new Random().nextInt(1000)); // 随机停留1s以内的时间
semaphore.release(); // 释放Semaphore许可
System.out.println(Thread.currentThread().getName() + " 离开了停车场。");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executorService.shutdown(); // 关闭线程池
}
}
运行结果如下:
pool-1-thread-1 进入了停车场。
pool-1-thread-2 进入了停车场。
pool-1-thread-2 离开了停车场。
pool-1-thread-3 进入了停车场。
pool-1-thread-4 进入了停车场。
pool-1-thread-1 离开了停车场。
pool-1-thread-3 离开了停车场。
pool-1-thread-5 进入了停车场。
pool-1-thread-4 离开了停车场。
pool-1-thread-5 离开了停车场。
可以看到,Semaphore实现了停车场的限流,只有2辆汽车能够同时进入停车场,其他的汽车需要等待前面的汽车离开才能进入。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java并发编程信号量Semapher - Python技术站