zoukankan      html  css  js  c++  java
  • Semaphore与CountDownLatch

    1、Semaphore

       它的作用是控制访问特定资源的线程数目,底层依赖AQS的状态state,是在生产中比较常见的一个工具类。

    2、Semaphore常见API

    public Semphore(int permits)
    public Semphore(int permits, boolean fair)
    // permits表示许可的线程数量
    // fair 表示公平性,如果设为true,下次执行的线程会是等待最久的线程
     public void acquire() throws InterruptedException
     public void release()
     // acquire 获取许可
     // release 释放许可
    import java.util.concurrent.Semaphore;
    
    public class SemaphoreRunner {
        public static void main(String[] args) {
            Semaphore semaphore = new Semaphore(2);
            for (int i=0;i<5;i++){
                new Thread(new Task(semaphore,"yangguo+"+i)).start();
            }
        }
    
        static class Task extends Thread{
            Semaphore semaphore;
    
            public Task(Semaphore semaphore,String tname){
                this.semaphore = semaphore;
                this.setName(tname);
            }
    
            public void run() {
                try {
                    semaphore.acquire();               
                    System.out.println(Thread.currentThread().getName()+":aquire() at time:"+System.currentTimeMillis());
                    Thread.sleep(1000);
                    semaphore.release();               
                    System.out.println(Thread.currentThread().getName()+":aquire() at time:"+System.currentTimeMillis());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
            }
        }
    }

    3、 CountDownLatch使用及应用场景

      CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成自己的任务后线程的值就会-1,当计数器的值为0时,表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

    CountDownLatch.countDown();
    CountDownLatch.await();
    import java.util.concurrent.CountDownLatch;
    
    /**
     * 看大夫任务
     */
    public class SeeDoctorTask implements Runnable {
        private CountDownLatch countDownLatch;
    
        public SeeDoctorTask(CountDownLatch countDownLatch){
            this.countDownLatch = countDownLatch;
        }
    
        public void run() {
            try {
                System.out.println("开始看医生");
                Thread.sleep(3000);
                System.out.println("看医生结束,准备离开病房");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                if (countDownLatch != null)
                    countDownLatch.countDown();
            }
        }
    
    }
    
    
    import java.util.concurrent.CountDownLatch;
    
    /**
     * 排队的任务
     */
    public class QueueTask implements Runnable {
    
        private CountDownLatch countDownLatch;
    
        public QueueTask(CountDownLatch countDownLatch){
            this.countDownLatch = countDownLatch;
        }
        public void run() {
            try {
                System.out.println("开始在医院药房排队买药....");
                Thread.sleep(5000);
                System.out.println("排队成功,可以开始缴费买药");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                if (countDownLatch != null)
                    countDownLatch.countDown();
            }
        }
    }
    
    
    import java.util.concurrent.CountDownLatch;
    
    /**
     * 配媳妇去看病,轮到媳妇看大夫时
     * 我就开始去排队准备交钱了。
     */
    public class CountDownLaunchRunner {
    
        public static void main(String[] args) throws InterruptedException {
            long now = System.currentTimeMillis();
            CountDownLatch countDownLatch = new CountDownLatch(2);
    
            new Thread(new SeeDoctorTask(countDownLatch)).start();
            new Thread(new QueueTask(countDownLatch)).start();
            //等待线程池中的2个任务执行完毕,否则一直
            countDownLatch.await();
            System.out.println("over,回家 cost:"+(System.currentTimeMillis()-now));
        }
    }
    import java.util.concurrent.CyclicBarrier;
    
    public class CyclicBarrierRunner implements Runnable {
        private CyclicBarrier cyclicBarrier;
        private int index;
    
        public CyclicBarrierRunner(CyclicBarrier cyclicBarrier, int index) {
            this.cyclicBarrier = cyclicBarrier;
            this.index = index;
        }
    
        public void run() {
            try {
                System.out.println("index: " + index);
                index--;
                cyclicBarrier.await();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) throws Exception {
            CyclicBarrier cyclicBarrier = new CyclicBarrier(11, new Runnable() {
                public void run() {
                    System.out.println("所有特工到达屏障,准备开始执行秘密任务");
                }
            });
            for (int i = 0; i < 10; i++) {
                new Thread(new CyclicBarrierRunner(cyclicBarrier, i)).start();
            }
            cyclicBarrier.await();
            System.out.println("全部到达屏障....");
        }
    }
    岁月本长而忙者自促;天地本宽而卑者自隘;风花雪月本闲,而劳忧者自冗;天行健,君子以自强不息;地势坤,君子以厚德载物;宠辱不惊,闲看庭前花开花落;去留无意,漫随天外云卷云舒.不妄取,不妄予,不妄想,不妄求,与人方便,随遇而安
  • 相关阅读:
    用XMLSocket获得SmartFoxServer的zone在线人数
    php mvc开发系列教程第一节 认识mvc
    使用java编写SmartFoxServer自定义安全验证登录扩展
    php mvc开发系列教程第二节 单一入口文件(路由文件)
    php mvc开发系列教程第三节 Controller 类实现
    [转]IE下对文件(图片)进行base64转换
    从TFS中的现有项目复制一份作为新项目
    在javascript中实现document.ready,实现点Export按钮后刷新页面
    SQL Server 2005 学习笔记系列文章
    How to Read XMLDocument into a SQL Sever XML field / saving XML to database or filesystem...best method?
  • 原文地址:https://www.cnblogs.com/vvning/p/13935690.html
Copyright © 2011-2022 走看看