14-Java5的Semaphere同步工具
范例:模拟一个银行柜台只有3个窗口,有10个客户过来办理业务
package cn.itcast.demo.thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class SemaphoreTest { public static void main(String[] args) { // 创建一个线程池对象 ExecutorService executorService = Executors.newCachedThreadPool(); // 创建信号灯数量(即资源的数量,比如只有3个座位) final int count = 3; //final Semaphore sp = new Semaphore(count); // 哪个客户先办理业务,是随机叫号的,不公平 final Semaphore sp = new Semaphore(count, true); // 先到的客户先办理业务,公平(或者可以设置VIP窗口) // 创建10个线程 for (int i=1; i<=10; i++) { Runnable runnable = new Runnable() { @Override public void run() { try { // 从信号灯中获取一个许可(即允许一个线程进入) sp.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程[ " + Thread.currentThread().getName() + " ]进入,当前已有[ " + (count-sp.availablePermits()) + " ]个并发"); try { Thread.sleep((long)Math.random()*10000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程[ " + Thread.currentThread().getName() + " ]即将离开"); // 释放一个信号灯许可,将其返回到信号量 sp.release(); // 下面的代码有时候执行不准确,因为没有和上面的代码合成原子性 System.out.println("线程[ " + Thread.currentThread().getName() + " ]已离开,当前已有[ " + (count-sp.availablePermits()) + " ]个并发"); } }; // 将任务放入线程池中 executorService.execute(runnable); } } }
打印结果:
线程[ pool-1-thread-1 ]进入,当前已有[ 1 ]个并发 线程[ pool-1-thread-5 ]进入,当前已有[ 2 ]个并发 线程[ pool-1-thread-2 ]进入,当前已有[ 3 ]个并发 线程[ pool-1-thread-2 ]即将离开 线程[ pool-1-thread-1 ]即将离开 线程[ pool-1-thread-1 ]已离开,当前已有[ 2 ]个并发 线程[ pool-1-thread-5 ]即将离开 线程[ pool-1-thread-5 ]已离开,当前已有[ 2 ]个并发 线程[ pool-1-thread-9 ]进入,当前已有[ 3 ]个并发 线程[ pool-1-thread-6 ]进入,当前已有[ 2 ]个并发 线程[ pool-1-thread-3 ]进入,当前已有[ 3 ]个并发 线程[ pool-1-thread-2 ]已离开,当前已有[ 3 ]个并发 线程[ pool-1-thread-3 ]即将离开 线程[ pool-1-thread-4 ]进入,当前已有[ 3 ]个并发 线程[ pool-1-thread-3 ]已离开,当前已有[ 3 ]个并发 线程[ pool-1-thread-9 ]即将离开 线程[ pool-1-thread-9 ]已离开,当前已有[ 2 ]个并发 线程[ pool-1-thread-8 ]进入,当前已有[ 3 ]个并发 线程[ pool-1-thread-6 ]即将离开 线程[ pool-1-thread-6 ]已离开,当前已有[ 2 ]个并发 线程[ pool-1-thread-7 ]进入,当前已有[ 3 ]个并发 线程[ pool-1-thread-4 ]即将离开 线程[ pool-1-thread-4 ]已离开,当前已有[ 2 ]个并发 线程[ pool-1-thread-10 ]进入,当前已有[ 3 ]个并发 线程[ pool-1-thread-8 ]即将离开 线程[ pool-1-thread-8 ]已离开,当前已有[ 2 ]个并发 线程[ pool-1-thread-7 ]即将离开 线程[ pool-1-thread-7 ]已离开,当前已有[ 1 ]个并发 线程[ pool-1-thread-10 ]即将离开 线程[ pool-1-thread-10 ]已离开,当前已有[ 0 ]个并发
以上结果不准确,需修改代码,合成原子性