首页 > 代码库 > JDK5新特性之线程同步工具类(三)
JDK5新特性之线程同步工具类(三)
一. Semaphore实现信号灯
Semaphore可以控制同时访问资源的线程个数, 例如: 实现一个文件允许的并发访问数.
Semaphore实现的功能就类似厕所有5个坑, 加入有十个人要上厕所, 那么同时只能有5个人能够占用, 当5个人中的任何一个人离开后, 其中在等待的另外5个人中就有一个可以占用了. 另外等待的5个人中可以是随机获得优先机会, 也可以使按照先来后到的顺序获得机会, 这取决于构造Semaphore对象时传入的参数选项.
/** * Semaphore:信号灯 */ public class SemaphoreTest { public static void main(String[] args) { // 创建一个线程池 ExecutorService es = Executors.newCachedThreadPool(); // 允许并发访问的线程个数为3个 final Semaphore sp = new Semaphore(3); // 开启10个线程 for (int i = 0; i < 10; i++) { es.execute(new Runnable() { @Override public void run() { try { sp.acquire(); // 获取信号灯 System.out.println("线程 " + Thread.currentThread().getName() + " 进入,当前有 " + (3 - sp.availablePermits()) + " 个并发!"); Thread.sleep(2000); System.out.println("线程 " + Thread.currentThread().getName() + " 即将离开!"); sp.release(); // 释放信号灯 System.out.println("线程 " + Thread.currentThread().getName() + " 离开,当前有 " + (3 - sp.availablePermits()) + " 个并发!"); } catch (InterruptedException e) { e.printStackTrace(); } } }); } } }
单个Semaphore对象可以实现互斥锁的功能, 并且可以是由一个线程获得了"锁", 再由另一个线程释放"锁", 这可应用于死锁恢复的一些场合.
public class CyclicBarrierTest { public static void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool(); final CyclicBarrier cb = new CyclicBarrier(3); // 创建3个线程 for(int i=0;i<3;i++){ service.execute(new Runnable(){ @Override public void run(){ try { Thread.sleep((long)(Math.random() * 10000));//每个线程“休息的”时间不同 System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点1,当前已有" + (cb.getNumberWaiting() + 1) + "个已经到达," + (cb.getNumberWaiting() == 2 ? "都到齐了,继续前进":"正在等候")); cb.await(); //先到的等待后到的,当3个都到达时才会继续向下执行 Thread.sleep((long)(Math.random() * 10000));//每个线程“休息的”时间不同 System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点2,当前已有" + (cb.getNumberWaiting() + 1) + "个已经到达," + (cb.getNumberWaiting() == 2 ? "都到齐了,继续前进":"正在等候")); cb.await(); Thread.sleep((long)(Math.random()*10000));//每个线程“休息的”时间不同 System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点3,当前已有" + (cb.getNumberWaiting() + 1) + "个已经到达,"+ (cb.getNumberWaiting() == 2 ? "都到齐了,继续前进":"正在等候")); cb.await(); } catch (Exception e) { e.printStackTrace(); } } }); } service.shutdown(); } }
JDK5新特性之线程同步工具类(三)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。