Semaphore类似于操作系统中的信号量,可以控制值对互斥资源的访问线程数。
举个例子:比如一共3把伞,9个人来借伞,伞借出去了就不能借给其他人,直到有人还伞。参考以下小demo理解以下。
package com.leo.demo.juctest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.*;
/**
* @ClassName: SemaphoreExample
* @Description: 关于Semaphore测试的小demo
* @Author: leo825
* @Date: 2020-05-10 15:35
* @Version: 1.0
*/
public class SemaphoreExample {
public static void main(String[] args) {
//假如有3把雨伞
final int umbrella = 3;
//假如有10个人借伞
final int persons = 9;
//设置信号量
Semaphore semaphore = new Semaphore(umbrella);
//定义一个线程池模拟借伞
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < persons; i++) {
executorService.execute(() -> {
try {
//借伞
semaphore.acquire();
getThreadLog("借伞成功,当前可接伞剩余:" + semaphore.availablePermits() + " 把");
//模拟借用时长
int times = ThreadLocalRandom.current().nextInt(10);
getThreadLog("借用时长为:" + times + " 天");
TimeUnit.MILLISECONDS.sleep(times);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
getThreadLog("还伞成功,当前可接伞剩余:" + semaphore.availablePermits() + " 把");
}
});
}
executorService.shutdown();
}
/**
* 获取线程名和时间
*
* @return
*/
public static void getThreadLog(String logContent) {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("[");
stringBuffer.append(Thread.currentThread().getName());
stringBuffer.append(" ");
stringBuffer.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));
stringBuffer.append("]");
stringBuffer.append(logContent);
System.out.println(stringBuffer.toString());
}
}
打印结果如下:
[pool-1-thread-3 2020-05-10 16:14:31.563]借伞成功,当前可接伞剩余:0 把
[pool-1-thread-2 2020-05-10 16:14:31.564]借伞成功,当前可接伞剩余:1 把
[pool-1-thread-1 2020-05-10 16:14:31.563]借伞成功,当前可接伞剩余:2 把
[pool-1-thread-2 2020-05-10 16:14:31.566]借用时长为:1 天
[pool-1-thread-3 2020-05-10 16:14:31.566]借用时长为:4 天
[pool-1-thread-1 2020-05-10 16:14:31.566]借用时长为:6 天
[pool-1-thread-4 2020-05-10 16:14:31.567]借伞成功,当前可接伞剩余:0 把
[pool-1-thread-2 2020-05-10 16:14:31.567]还伞成功,当前可接伞剩余:1 把
[pool-1-thread-4 2020-05-10 16:14:31.567]借用时长为:9 天
[pool-1-thread-5 2020-05-10 16:14:31.570]借伞成功,当前可接伞剩余:0 把
[pool-1-thread-3 2020-05-10 16:14:31.570]还伞成功,当前可接伞剩余:1 把
[pool-1-thread-5 2020-05-10 16:14:31.570]借用时长为:0 天
[pool-1-thread-5 2020-05-10 16:14:31.571]还伞成功,当前可接伞剩余:1 把
[pool-1-thread-6 2020-05-10 16:14:31.571]借伞成功,当前可接伞剩余:0 把
[pool-1-thread-6 2020-05-10 16:14:31.571]借用时长为:0 天
[pool-1-thread-6 2020-05-10 16:14:31.572]还伞成功,当前可接伞剩余:1 把
[pool-1-thread-7 2020-05-10 16:14:31.572]借伞成功,当前可接伞剩余:0 把
[pool-1-thread-1 2020-05-10 16:14:31.572]还伞成功,当前可接伞剩余:1 把
[pool-1-thread-8 2020-05-10 16:14:31.572]借伞成功,当前可接伞剩余:0 把
[pool-1-thread-7 2020-05-10 16:14:31.572]借用时长为:8 天
[pool-1-thread-8 2020-05-10 16:14:31.573]借用时长为:8 天
[pool-1-thread-4 2020-05-10 16:14:31.576]还伞成功,当前可接伞剩余:1 把
[pool-1-thread-9 2020-05-10 16:14:31.576]借伞成功,当前可接伞剩余:0 把
[pool-1-thread-9 2020-05-10 16:14:31.577]借用时长为:9 天
[pool-1-thread-8 2020-05-10 16:14:31.581]还伞成功,当前可接伞剩余:2 把
[pool-1-thread-7 2020-05-10 16:14:31.581]还伞成功,当前可接伞剩余:2 把
[pool-1-thread-9 2020-05-10 16:14:31.587]还伞成功,当前可接伞剩余:3 把
可以从日志中看出,当有伞的时候才可以借,也就是说谁还了伞,下一个人才可以借用,这就是信号量,主要控制互斥资源的访问。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/72712.html