- 简介
Semaphore主要是在多线程中可以轻松控制信号量,针对某个资源可被并发访问的个数。acquire()方法可以或得一个访问的许可,release()方法释放一个许可。提供同步机制,控制同时访问的个数。
- 应用场景举例
模拟银行窗口处理业务情景同时有5个窗口处理业务,有10个顾客等待
- 代码示例
import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.Semaphore; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * User: ww.wang * Date: 2016/8/26 * Time: 17:12 */ public class TestSemaphore { public static void main(String[] args){ //构造线程池 ExecutorService executorService = new ThreadPoolExecutor(5,10,3000, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<>(100)); //构造信号量 5 Semaphore semaphore = new Semaphore(5); //模拟 10个顾客等待银行 5个窗口办理业务 for (int i=1;i<=10;i++){ final int customID = i; Runnable runnable = new Runnable(){ @Override public void run() { try { semaphore.acquire(); System.out.println("客户"+customID+"正在办理业务"); //业务办理时间为随机几秒钟 long time = (long)(Math.random()*10000); Thread.sleep(time); System.out.println("客户"+customID+"办理业务花费了"+time+"毫秒"); semaphore.release(); System.out.println("客户"+customID+"办理业务结束"); } catch (InterruptedException e) { e.printStackTrace(); } } }; executorService.submit(runnable); } //关闭线程池 executorService.shutdown(); } }
- 运行结果
"C:\Program Files\Java\jdk1.8.0_66\bin\java" -Didea.launcher.port=7535 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA 15.0.6\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_66\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_66\jre\lib\rt.jar;D:\work\eb\ebredesign\code\gitprojects\leo\out\production\leo;C:\Program Files (x86)\JetBrains\IntelliJ IDEA 15.0.6\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain TestSemaphore 客户1正在办理业务 客户2正在办理业务 客户3正在办理业务 客户4正在办理业务 客户5正在办理业务 客户1办理业务花费了936毫秒 客户1办理业务结束 客户6正在办理业务 客户2办理业务花费了2556毫秒 客户2办理业务结束 客户7正在办理业务 客户6办理业务花费了2504毫秒 客户6办理业务结束 客户8正在办理业务 客户7办理业务花费了2057毫秒 客户7办理业务结束 客户9正在办理业务 客户5办理业务花费了4982毫秒 客户5办理业务结束 客户10正在办理业务 客户4办理业务花费了7183毫秒 客户4办理业务结束 客户9办理业务花费了3444毫秒 客户9办理业务结束 客户3办理业务花费了9197毫秒 客户3办理业务结束 客户10办理业务花费了4501毫秒 客户10办理业务结束 客户8办理业务花费了6619毫秒 客户8办理业务结束 Process finished with exit code 0
- 总结
以上代码测试可以看出,五个窗口同时工作,10个顾客等等待,然而通知处理业务的客户一直是5个
客户1 办理结束
客户6开始办理
一个释放许可一个获取。
拓展:如果再加个vip窗口,在加5个vip客户 ,vip窗口只处理vip客户,普通窗口 如果有vip就优先处理vip 这个业务又如何实现呢